
[SQL][問題處理]肥得要死的 tempdb 如何縮減
https://dotblogs.com.tw/jamesfu/2014/05/20/shrinktempdb
可以參考 Technet 上的文章,一般來說當你連線結束之後,所佔用的資源應該會被釋放,但目前他們的 tempdb 會長到那麼大的話,我們直接使用壓縮指令又無法壓縮的狀況下,因此建議朋友先使用以下的指令來試試看:
-- 避免還有資料還在記憶體內,手動進行 Checkpoint
Checkpoint
GO
-- 強制釋放佔用的記憶體
DBCC FREESYSTEMCACHE ('ALL')
DBCC FREEPROCCACHE
DBCC DROPCLEANBUFFERS
DBCC FREESESSIONCACHE
GO
完成上述指令之後,再重新進行一次壓縮 tempdb,果然就可以順利把 tempdb 給壓縮了。
DBCC SHRINKDATABASE(N'tempdb')
SQL TABLE內資料的全文檢索
感謝保哥,讚嘆保哥
DECLARE @SearchStr nvarchar(200) = N'使用者本文'
-- Copyright © 2002 Narayana Vyas Kondreddi. All rights reserved.
-- Purpose: To search all columns of all tables for a given search string
-- Written by: Narayana Vyas Kondreddi
-- Site: http://vyaskn.tripod.com
-- Tested on: SQL Server 7.0 and SQL Server 2000
-- Date modified: 28th July 2002 22:50 GMT
CREATE TABLE #Results (ColumnName nvarchar(370), ColumnValue nvarchar(3630))
SET NOCOUNT ON
DECLARE @TableName nvarchar(256), @ColumnName nvarchar(128), @SearchStr2 nvarchar(110)
SET @TableName = ''
SET @SearchStr2 = QUOTENAME('%' + @SearchStr + '%','''')
WHILE @TableName IS NOT NULL
BEGIN
SET @ColumnName = ''
SET @TableName =
(
SELECT MIN(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME))
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE'
AND QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) > @TableName
AND OBJECTPROPERTY(
OBJECT_ID(
QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)
), 'IsMSShipped'
) = 0
)
WHILE (@TableName IS NOT NULL) AND (@ColumnName IS NOT NULL)
BEGIN
SET @ColumnName =
(
SELECT MIN(QUOTENAME(COLUMN_NAME))
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = PARSENAME(@TableName, 2)
AND TABLE_NAME = PARSENAME(@TableName, 1)
AND DATA_TYPE IN ('char', 'varchar', 'nchar', 'nvarchar')
AND QUOTENAME(COLUMN_NAME) > @ColumnName
)
IF @ColumnName IS NOT NULL
BEGIN
INSERT INTO #Results
EXEC
(
'SELECT ''' + @TableName + '.' + @ColumnName + ''', LEFT(' + @ColumnName + ', 3630)
FROM ' + @TableName + ' (NOLOCK) ' +
' WHERE ' + @ColumnName + ' LIKE ' + @SearchStr2
)
END
END
END
SELECT * FROM #Results
DROP TABLE #Results
LINK SERVER的怪問題
情境:
LINK到另一台的SP將SELECT結果取回入TEMP,但會出現”無法執行作業,因為連結伺服器 “ESWEB1” 的 OLE DB 提供者 “SQLNCLI10” 無法開始分散式交易。”的錯誤訊息
改DTC也無效(https://dotblogs.com.tw/abbee/2017/01/20/163135)
EXEC sp_configure exec sp_configure 'show advanced options', 1; RECONFIGURE; exec sp_configure 'Ad Hoc Distributed Queries', 1; RECONFIGURE; GO
原語法:
insert into #tmp exec [link].SP
改為OPENQUERY:
insert into #tmp select * from openquery([link],'SET FMTONLY OFF;SET NOCOUNT ON;exec SP')
SQL定序
CaseSensitivity
CI 指定不區分大小寫,CS 指定區分大小寫。
AccentSensitivity
AI 指定不區分腔調字,AS 指定區分腔調字。
BIN
指定要用的二進位排序次序。
SQL帳號孤兒
https://dotblogs.com.tw/pei_hsin/2012/01/28/67053
最大群組關聯
近期遇到最難的邏輯
if object_id('tempdb..#IL_Benson') is not null
drop table #IL_Benson ;
create table #IL_Benson (
ActSeq varchar(19) --18
, GCNo varchar(21) --21
, ActSeq_T varchar(19)
, GCNo_T varchar(21)
, RUN int default 0) ;
insert into #IL_Benson (ActSeq, GCNo)
values ('ACT1', 'A')
, ('ACT2', 'B'), ('ACT2', 'C'), ('ACT2', 'D')
, ('ACT3', 'A'), ('ACT3', 'C')
, ('ACT4', 'D')
, ('ACT5', 'D'), ('ACT5', 'E')
, ('ACT6', 'F'), ('ACT6', 'G')
, ('ACT7', 'F')
, ('ACT8', 'G'), ('ACT8', 'H')
, ('ACT9', 'Z')
/*
update a
set a.RUN = 0
, a.ActSeq_T = null
, a.GCNo_T = null
from #IL_Benson a
select a.ActSeq, a.GCNo, a.ActSeq_T, a.GCNo_T, a.RUN
from #IL_Benson a
order by 1, 2
*/
--資料檢測,RUN<0
--(RUN=-1) 1 ACT to 1 GC
update a
set a.ActSeq_T = a.ActSeq
, a.GCNo_T = a.GCNo
, a.RUN = -1
from #IL_Benson a
inner join (
select a.ActSeq, count(distinct a.GCNo) CNT
from #IL_Benson a
group by a.ActSeq
having count(distinct a.GCNo) = 1 ) b
on a.ActSeq = b.ActSeq
inner join (
select a.GCNo, count(distinct a.ActSeq) CNT
from #IL_Benson a
group by a.GCNo
having count(distinct a.ActSeq) = 1 ) c
on a.GCNo = c.GCNo
;
--(RUN=-2) 1 ACT to Multi GC and 1 GC to 1 ACT
update a
set a.ActSeq_T = a.ActSeq
, a.GCNo_T = b.GCNo_T
, a.RUN = -2
--select count(*)
from #IL_Benson a
inner join (
select a.ActSeq, count(distinct a.GCNo) CNT, min(a.GCNo) GCNo_T
from #IL_Benson a
group by a.ActSeq
having count(distinct a.GCNo) > 1 ) b
on a.ActSeq = b.ActSeq
inner join (
select b.ActSeq, count(distinct a.ActSeq) cnt
from #IL_Benson a
inner join (
select a.ActSeq, a.GCNo
from #IL_Benson a
inner join (
select a.ActSeq, count(distinct a.GCNo) CNT
from #IL_Benson a
group by a.ActSeq
having count(distinct a.GCNo) > 1 ) b
on a.ActSeq = b.ActSeq ) b
on a.GCNo = b.GCNo
group by b.ActSeq
having count(distinct a.ActSeq) = 1 ) c
on a.ActSeq = c.ActSeq
where a.ActSeq_T is null
and a.GCNo_T is null
;
--(RUN=-3) 1 ACT to 1 GC and 1 GC to Multi ACT
update a
set a.ActSeq_T = b.ActSeq_T
, a.GCNo_T = a.GCNo
, a.RUN = -3
--select count(*)
from #IL_Benson a
inner join (
select a.GCNo, count(distinct a.ActSeq) CNT, min(a.ActSeq) ActSeq_T
from #IL_Benson a
group by a.GCNo
having count(distinct a.ActSeq) > 1 ) b
on a.GCNo = b.GCNo
inner join (
select b.GCNo, count(distinct a.GCNo) cnt
from #IL_Benson a
inner join (
select a.ActSeq, a.GCNo
from #IL_Benson a
inner join (
select a.GCNo, count(distinct a.ActSeq) CNT
from #IL_Benson a
group by a.GCNo
having count(distinct a.ActSeq) > 1 ) b
on a.GCNo = b.GCNo ) b
on a.ActSeq = b.ActSeq
group by b.GCNo
having count(distinct a.GCNo) = 1
) c
on a.GCNo = c.GCNo
where a.ActSeq_T is null
and a.GCNo_T is null
;
--select * from #IL_Benson
--------------------------------------
--補衍伸關聯資料,RUN=1
DECLARE @RC INT
DECLARE @RUN INT
select @RC = count(*)
--select count(*)
from #IL_Benson a
where a.ActSeq_T is null
WHILE @RC > 0
BEGIN
SET @RC = 0
insert into #IL_Benson (ActSeq, GCNo, RUN)
select distinct b.ActSeq_T ActSeq, a.GCNo, 1
from #IL_Benson a
inner join (
select distinct b.ActSeq ActSeq_T, a.ActSeq, b.GCNo
from #IL_Benson a
inner join (
select distinct a.ActSeq, a.GCNo
from #IL_Benson a
where a.ActSeq_T is null
--and a.ActSeq = '3'
) b
on a.GCNo = b.GCNo ) b
on a.ActSeq = b.ActSeq
left outer join #IL_Benson c
on b.ActSeq_T = c.ActSeq
and a.GCNo = c.GCNo
and c.ActSeq_T is null
where a.ActSeq_T is null
and c.ActSeq is null
set @RC = @RC + @@ROWCOUNT
--select * from #IL_Benson where Run=1
insert into #IL_Benson (ActSeq, GCNo, RUN)
select distinct a.ActSeq, b.GCNo_T GCNo, 1
from #IL_Benson a
inner join (
select distinct b.GCNo GCNo_T, b.ActSeq, a.GCNo
from #IL_Benson a
inner join (
select distinct a.ActSeq, a.GCNo
from #IL_Benson a
where a.ActSeq_T is null
--and a.GCNo = 'D'
) b
on a.ActSeq = b.ActSeq ) b
on a.GCNo = b.GCNo
left outer join #IL_Benson c
on a.ActSeq = c.ActSeq
and b.GCNo_T = c.GCNo
and c.ActSeq_T is null
where a.ActSeq_T is null
and c.ActSeq is null
set @RC = @RC + @@ROWCOUNT
--select * from #IL_Benson where Run=1
--select a.RUN, count(*)
--from #IL_Benson a
--where a.ActSeq_T is null
--group by a.RUN
END
update a
set a.ActSeq_T = a.ActSeq
, a.GCNo_T = a.GCNo
from #IL_Benson a
where a.ActSeq_T is null
and a.GCNo_T is null
--select * from #IL_Benson order by ActSeq_T,GCNo_T
--------------------------------------
declare @RC INT
select @RC = count(*)
from #IL_Benson a
where a.RUN >= 0
--select @RC
WHILE @RC > 0
BEGIN
SET @RC = 0
update a
set a.ActSeq_T = b.ActSeq
--select count(*)
from #IL_Benson a
inner join (
select a.GCNo GCNo, min(a.ActSeq) ActSeq
from #IL_Benson a
where a.RUN >= 0
group by a.GCNo ) b
on a.GCNo_T = b.GCNo
and a.ActSeq_T <> b.ActSeq
where a.RUN >= 0
SET @RC = @RC + @@ROWCOUNT
update a
set a.GCNo_T = b.GCNo
--select count(*)
from #IL_Benson a
inner join (
select a.ActSeq ActSeq, min(a.GCNo) GCNo
from #IL_Benson a
where a.RUN >= 0
group by a.ActSeq ) b
on a.ActSeq_T = b.ActSeq
and a.GCNo_T <> b.GCNo
where a.RUN >= 0
SET @RC = @RC + @@ROWCOUNT
END
--select * from #IL_Benson order by ActSeq,GCNo
寫入Linked Server遇到的問題
讀取遠端SP,將結果集收回本機,找到以下解法:
https://dotblogs.com.tw/abbee/2017/01/20/163135
原以為此問題只能用DTC設定解決,
但其實有OPENQUERY的方法可解
INSERT INTO #tmp
--exec [10.11.36.52].[ELOANDB].dbo.SP_ONLINE_8888_TO_DW
SELECT *
FROM OPENROWSET('SQLOLEDB','IP,1433';'帳號';'密碼','SET FMTONLY OFF; EXEC DB.dbo.SP_NAME')
SQL Server中獲得EXEC的值
declare @rsql Varchar(250) declare @csql Varchar(300) declare @rc Nvarchar(500) declare @cstucount int declare @ccount int set @rsql='(select Classroom_id from EA_RoomTime where zc='+@zc+' and xq='+@xq+' and T'+@time+'=''否'') and ClassroomType=''1''' --exec(@rsql) set @csql='select @a=sum(teststucount),@b=sum(classcount) from EA_ClassRoom where classroom_id in ' set @rc=@csql+@rsql exec sp_executesql @rc,N'@a int output,@b int output',@cstucount output,@ccount output--將exec的結果放入變數中的做法 --select @csql+@rsql
–select @cstucount上面的@rc這個sql語句的功能是找出特定時間段裡所有有空的教室數量以及這些教室所能容納的學生人數,因為涉及到動態的sql語句(@csql這句裡條件中有一個列名是動態變化的)的構造,所以要放在exec裡執行,但是同時我又要返回2個結果,所以執行時的代碼為:
exec sp_executesql @rc,N'@a int output,@b int output',@cstucount output,@ccount output--將exec的結果放入變數中的做法
這樣就將傳回值放到了,@cstucount,@ccount兩個變數中,得到了我們想要的結果。
我們來看一個簡單的預存程序:
create procedure ProTest ( @name Varchar(10), @money int output ) as begin if(@name='1') set @money=1000 else set @money=2000 end
這個只是一個簡單的示例,這個預存程序返回的是@money 這個參數的值,那麼當我們在另外一個預存程序中調用此預存程序的時候如何獲取這個參數呢,方法如下:
declare @m int ---用來接收傳回值的變數 exec ProTest @name='1',@money=@m output --一定要注名是output
就這麼簡單,我們就獲得了傳回值,然後就可以利用它了。

