1. 程式人生 > >如何同時對多個表或列操作

如何同時對多個表或列操作

lac procedure states lag nds 過濾 遊標 字符 ret

通過使用這個存儲過程,你就可以方便的對數據庫中具有一定規則的或者全部表,對這裏的字段進行各種操作,具體看示例!

CREATE PROCEDURE SP_execSQLonDB
(@TABLENAME VARCHAR(50), --表名條件
@COLUMNNAME VARCHAR(50), --字段條件
@SQL NVARCHAR(4000), --執行的SQL
@INCLUDE_NTI CHAR(1) = ‘N‘) --是否包含Text,NText,Image數據類
AS
BEGIN
--Variable Declaration
--變量定義


DECLARE @strSQL NVARCHAR(4000)
DECLARE @SQL2 NVARCHAR(4000)
DECLARE @sTableName VARCHAR(200)
DECLARE @sColumnName VARCHAR(200)

DECLARE @SQLTemp NVARCHAR(4000)

--Check whether to include TEXT, NTEXT, IMAGE data types
--檢查是否需要包含 Text,NText,Image數據類型

SET @INCLUDE_NTI = UPPER(LTRIM(RTRIM(@INCLUDE_NTI)))
IF @INCLUDE_NTI NOT IN (‘N‘, ‘Y‘)
SET @INCLUDE_NTI = ‘N‘

--Construct a cursor to get the list of Table/Column Names according to the @TABLENAME and @COLUMNNAME parameters.
--創建一個遊標來讀取表名和列名的列表,[email protected] 和 @COLUMNNAME 決定
SET @strSQL = N‘DECLARE TabColCursor CURSOR FOR SELECT RTRIM(LTRIM(SU.name)) + ‘‘.‘‘ + LTRIM(RTRIM(SO.name)), SC.name FROM sysobjects SO INNER JOIN syscolumns SC ON SO.id = SC.id INNER JOIN sysusers SU ON SO.uid = SU.uid WHERE SO.xtype = ‘‘U‘‘ ‘

--Filter out Text/NText/Image data types if it is not included
--假如不包含Text/NText/Image數據類型,把他們過濾掉

IF @INCLUDE_NTI = ‘N‘
--In SysColumns sytem table XTYPE column corresponds to Column Data Type
SET @strSQL = @strSQL + ‘ AND SC.xtype NOT IN (35, 99, 34) ‘

--Add the TABLE(S) name i.e. filter if it is supplied
--假如有提供表名參數,把它寫入過濾條件中

IF @TABLENAME IS NOT NULL AND ltrim(rtrim(@TABLENAME)) <> ‘‘
BEGIN
SET @TABLENAME = REPLACE(@TABLENAME, ‘, ‘, ‘,‘)
SET @strSQL = @strSQL + ‘ AND (SO.name LIKE ‘‘‘ + REPLACE(@TABLENAME, ‘,‘, ‘‘‘ OR SO.name LIKE ‘‘‘) + ‘‘‘)‘
SET @SQLTemp= ‘ AND (SO.name LIKE ‘‘‘ + REPLACE(@TABLENAME, ‘,‘, ‘‘‘ OR SO.name LIKE ‘‘‘) + ‘‘‘)‘
END

--Add the COLUMN(S) name i.e. filter if it is supplied
--假如有提供列名參數,把它寫入過濾條件中

IF @COLUMNNAME IS NOT NULL AND ltrim(rtrim(@COLUMNNAME)) <> ‘‘
BEGIN
SET @COLUMNNAME = REPLACE(@COLUMNNAME, ‘, ‘, ‘,‘)
SET @strSQL = @strSQL + ‘ AND (SC.name LIKE ‘‘‘ + REPLACE(@COLUMNNAME, ‘,‘, ‘‘‘ OR SC.name LIKE ‘‘‘) + ‘‘‘)‘
END

--Execute the constructed "Cursor Declaration" string
--執行定義遊標的SQL語句

EXECUTE sp_executesql @strSQL

IF @@ERROR > 0
BEGIN
PRINT ‘Error while declaring the Cursor. Please check out the parameters supplied to the Procedure‘
RETURN -1
END

--Database Transaction.
--標記一個顯式本地事務的起始點

BEGIN TRANSACTION gDatabaseTrans

--Open the cursor
--打開遊標

OPEN TabColCursor

--Fetch te Table, Column names to variables
--用遊標取出標名、列名對應到參數

FETCH NEXT FROM TabColCursor
INTO @sTableName, @sColumnName

--Execute the SQL statement supplied in @SQL parameter on every row of Cursor‘s data
--對於每一行遊標取出的數據,[email protected]
WHILE @@FETCH_STATUS = 0
BEGIN
--Construct SQL2 to Execute supplied @SQL
--by replacing @TABLENAME, @COLUMNNAME with running Table Name, Column Name of Cursor‘s data
[email protected]@TABLENAME, @COLUMNNAME來構造SQL2

SET @SQL2 = @SQL
SET @SQL2 = REPLACE(@SQL2, [email protected], @sTableName)
SET @SQL2 = REPLACE(@SQL2, [email protected], @sColumnName)

--Execute the constructed SQL2
--執行SQL2

EXECUTE sp_executesql @SQL2

--Check for errors
--檢查錯誤

IF @@ERROR <> 0
BEGIN
--On Error, Destroy objects, Rollback transaction
--Return -1 as UNSUCCESSFUL flag
--如果發生錯誤,刪除遊標,回滾
--返回錯誤標記 -1

PRINT ‘Error occurred‘
DEALLOCATE TabColCursor
ROLLBACK TRANSACTION gDatabaseTrans
RETURN -1
END

--Process Next Row of Cursor
--進行下一行數據

FETCH NEXT FROM TabColCursor
INTO @sTableName,@sColumnName
END

--Destroy CURSOR object
--刪除遊標

DEALLOCATE TabColCursor

--Procedure executed properly. Commit the Transaction.
--Return 0 as SUCCESSFUL flag
--成功完成存儲過程,成功結束事務
--返回成功標記 0

COMMIT TRANSACTION gDatabaseTrans
RETURN 0
END

使用例子

1、這個例子在NORTHWIND數據庫上執行
把所有表中列名包含Name的列中,把以“Ltd.”結尾的列替換成“LIMITED”。
用 SELECT * FROM Suppliers檢查運行結果!

EXEC SP_execSQLonDB
‘‘, --沒有表名條件,針對所有表
‘%Name%‘, --列名條件,列名包含“Name”字符串
‘UPDATE @TABLENAME SET @COLUMNNAME = REPLACE(@COLUMNNAME,‘‘Ltd.‘‘,‘‘LIMITED‘‘)
WHERE @COLUMNNAME LIKE ‘‘%Ltd.‘‘‘, --UPDATE 語句
‘N‘ --不包含NTEXT,TEXT,IMAGE數據類型

2、這個例子也在NORTHWIND數據庫上執行
統計所有表中列名包含Name的列的值是“QUICK-Stop”的數量
create table ##TMP1 (table_name varchar(200),column_name varchar(200),rou_count int)
exec SP_execSQLonDB
‘‘,
‘%Name%‘,
‘DECLARE @iCount as int
SELECT @iCount=COUNT(1) FROM @TABLENAME WHERE @COLUMNNAME = ‘‘QUICK-Stop‘‘
IF @iCount >0
INSERT INTO ##TMP1 SELECT [email protected],[email protected],@iCount‘,
‘N‘
select * from ##TMP1

3、這個例子自己理解
針對所有以“EMPLOYEE”開頭的表,以“DEPT”開頭的字段執行存儲過程。
EXEC SP_execSQLonDB
‘EMPLOYEE%‘,
‘DEPT%‘,
‘EXEC USP_DeptStates [email protected],[email protected],
‘N‘

4、還是自己理解
[email protected] @COLUMNNAME參數給於多個值!
EXEC SP_execSQLonDB
‘EMPLOYEE%,PF%‘,
‘SALARY,%AMOUNT%‘,
‘EXEC USP_EMPLOYEE_PF ‘,
‘N‘

如何同時對多個表或列操作