[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
就這麼簡單,我們就獲得了傳回值,然後就可以利用它了。