我有我想要應用於許多表的代碼,而不是簡單地複製和替換表名,我想使用某種循環或光標來簡化事情。動態SQL中的循環
我設想設置我的表名稱的數組,並使用索引來遍歷列表,檢索每個表名稱並使用動態SQL來散佈表格名稱(如果適用的話在我的代碼中)。
由於沒有'數組'構造,據我所知,在SQL中,我不知道這是如何工作的。
有關如何解決這個問題的任何想法?
我有我想要應用於許多表的代碼,而不是簡單地複製和替換表名,我想使用某種循環或光標來簡化事情。動態SQL中的循環
我設想設置我的表名稱的數組,並使用索引來遍歷列表,檢索每個表名稱並使用動態SQL來散佈表格名稱(如果適用的話在我的代碼中)。
由於沒有'數組'構造,據我所知,在SQL中,我不知道這是如何工作的。
有關如何解決這個問題的任何想法?
這裏是做這件事的一種方法:
--Declare a table variable to hold your table names (and column names in case needed)
declare @listOfTablesToUpdate table (tableName varchar(100), columnNameToUpdate varchar(50))
--insert the tables that you want to work with.
insert into @listOfTablesToUpdate values ('Table1', 'column2')
insert into @listOfTablesToUpdate values ('Table2', 'column3')
insert into @listOfTablesToUpdate values ('Table3', 'column4')
--Cursor for iterating
declare @tableCursor cursor,
@tableName varchar(100),
@columnName varchar(50)
set @tableCursor = cursor for select * from @listOfTablesToUpdate
open @tableCursor
fetch next from @tableCursor into @tableName, @columnName
while(@@fetch_status = 0)
begin
--dynamic sql
declare @sql varchar(max)
--Your logic here...this is just an example
set @sql = 'update '[email protected]+' set '[email protected]+' = '+<value>+' where '[email protected] +' = '+<someothervalue>
exec @sql
fetch next from @tableCursor into @tableName, @columnName
end
close @tableCursor
deallocate @tableCursor
另一種方法包括:準備一個輔助功能,並允許一個不同的SQL語句應用到每個對象的程序(表,數據庫,等等)在一個列表中。幫助器函數來自SSRS Parameter question,並將逗號分隔列表拆分爲表格。
-- from https://stackoverflow.com/questions/512105/passing-multiple-values-for-a-single-parameter-in-reporting-services
CREATE FUNCTION [dbo].[fn_MVParam]
(@RepParam NVARCHAR(4000), @Delim CHAR(1)= ',')
RETURNS @Values TABLE (Param NVARCHAR(4000))AS
BEGIN
DECLARE @chrind INT
DECLARE @Piece NVARCHAR(100)
SELECT @chrind = 1
WHILE @chrind > 0
BEGIN
SELECT @chrind = CHARINDEX(@Delim,@RepParam)
IF @chrind > 0
SELECT @Piece = LEFT(@RepParam,@chrind - 1)
ELSE
SELECT @Piece = @RepParam
INSERT @Values(Param) VALUES(CAST(@Piece AS VARCHAR))
SELECT @RepParam = RIGHT(@RepParam,LEN(@RepParam) - @chrind)
IF LEN(@RepParam) = 0 BREAK
END
RETURN
END
GO
下面是ProcessListSQL過程的代碼。
-- @SQL to execute shall include {RP} as the replacement expression that
-- will evaluate to all the items in the comma delimited list
-- Also, please include a double quote " rather than two single quotes ''
-- in the input statement.
CREATE PROCEDURE [dbo].[ProcessListSQL] (
@CommaDelimitedList AS NVARCHAR(MAX),
@SQLtoExecute AS NVARCHAR(MAX))
AS BEGIN
DECLARE @Statements TABLE
( PK INT IDENTITY(1,1) PRIMARY KEY,
SQLObject NVARCHAR (MAX)
)
SET @SQLtoExecute = REPLACE (@SQLtoExecute, '"', '''')
INSERT INTO @Statements
SELECT PARAM FROM [dbo].[fn_MVParam](@CommaDelimitedList,',')
DECLARE @i INT
SELECT @i = MIN(PK) FROM @Statements
DECLARE @max INT
SELECT @max = MAX(PK) FROM @Statements
DECLARE @SQL AS NVARCHAR(MAX) = NULL
DECLARE @Object AS NVARCHAR(MAX) = NULL
WHILE @i <= @max
BEGIN
SELECT @Object = SQLObject FROM @Statements WHERE PK = @i
SET @SQL = REPLACE(@SQLtoExecute, '{RP}', @Object)
-- Uncommend below to check the SQL
-- PRINT @SQL
EXECUTE sp_executesql @SQL
SELECT @Object = NULL
SELECT @SQL = NULL
SET @i = @i + 1
END
END
GO
ProcessListSQL過程需要兩個參數。第一個是逗號分隔的字符串,其中包含將要循環的對象列表。第二個參數是一個字符串,其中包含將與第一個參數中的每個對象一起執行的SQL。
在下面的例子中,創建了四個數據庫。請注意,{rp}被第一個參數中的每個對象替換,並且在SQL語句中需要單引號的每個地方都需要雙引號。
EXECUTE ProcessListSQL 'rice,apples,cheese,tomatos',
'CREATE DATABASE [{rp}] CONTAINMENT = NONE
ON PRIMARY (NAME = N"{rp}",
FILENAME = N"D:\data\user\{rp}.mdf" ,
SIZE = 4096KB ,
FILEGROWTH = 1024KB)
LOG ON
(NAME = N"{rp}_log",
FILENAME = N"D:\DATA\USER\{rp}_log.ldf" ,
SIZE = 1024KB ,
FILEGROWTH = 10%)'
+1表變量是工作就像一個魅力陣列 – brian
一個偉大的替代,謝謝! – Chris