2011-12-02 22 views
6

Tôi có mã mà tôi muốn áp dụng cho một số bảng nhưng thay vì chỉ sao chép và thay thế tên bảng, tôi muốn sử dụng một số loại vòng lặp hoặc con trỏ để đơn giản hóa mọi thứ.Vòng trong SQL động

Tôi hình dung thiết lập một mảng tên bảng và sử dụng chỉ mục để lặp qua danh sách, truy xuất từng tên bảng và sử dụng SQL động để phân tách tên bảng nếu có trong mã của tôi.

Vì không có cấu trúc 'mảng', theo như tôi biết, trong SQL, tôi không chắc chắn cách thức này sẽ hoạt động.

Bất kỳ ý tưởng nào về cách thực hiện việc này?

Trả lời

7

Dưới đây là một cách để làm việc đó:

--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 
+1

+1 Biến bảng là sự thay thế tuyệt vời cho mảng – brian

+0

Làm việc như một sự quyến rũ, cảm ơn! – Chris

0

cách tiếp cận khác liên quan đến việc chuẩn bị một hàm helper và một thủ tục cho phép một để áp dụng câu lệnh SQL khác nhau cho từng đối tượng (bảng, cơ sở dữ liệu, vân vân) trong một danh sách. Hàm trợ giúp xuất phát từ một số SSRS Parameter question và chia tách một danh sách được phân cách bằng dấu phẩy thành một bảng.

-- 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 

Dưới đây là mã cho quy trình 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 

Quy trình ProcessListSQL lấy hai tham số. Đầu tiên là một chuỗi phân cách bằng dấu phẩy có chứa danh sách các đối tượng sẽ được quay vòng qua. Tham số thứ hai là một chuỗi chứa SQL sẽ được thực hiện với mỗi đối tượng trong tham số đầu tiên.

Trong ví dụ dưới đây, bốn cơ sở dữ liệu được tạo. Lưu ý rằng {rp} được thay thế bằng mỗi đối tượng trong tham số đầu tiên và dấu ngoặc kép là cần thiết ở mỗi vị trí cần có dấu nháy đơn trong câu lệnh 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%)' 
Các vấn đề liên quan