2011-12-02 14 views
6

के अंदर लूप मेरे पास कोड है कि मैं कई तालिकाओं पर आवेदन करना चाहता हूं लेकिन तालिका नामों की प्रतिलिपि बनाने और प्रतिस्थापित करने के बजाय, मैं चीजों को सरल बनाने के लिए किसी प्रकार का लूप या कर्सर का उपयोग करना चाहता हूं।गतिशील एसक्यूएल

मैं अपने टेबल नामों की एक सरणी सेट अप करने और सूची में पुनरावृत्त करने के लिए एक इंडेक्स का उपयोग करके, प्रत्येक तालिका नाम को पुनर्प्राप्त करने और तालिका कोड को घुमाने के लिए गतिशील एसक्यूएल का उपयोग करके अपने कोड में लागू होने का अनुमान लगाता हूं।

चूंकि एसक्यूएल के भीतर, जहां तक ​​मुझे पता है, कोई 'सरणी' निर्माण नहीं है, मुझे यकीन नहीं है कि यह कैसे काम करेगा।

इस बारे में कोई विचार कैसे है?

उत्तर

7

यहाँ यह ऐसा करने का एक तरीका है:

--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 तालिका चर एरे के लिए एक महान प्रतिस्थापन हैं – brian

+0

एक आकर्षण की तरह काम किया, धन्यवाद! – Chris

0

एक और दृष्टिकोण एक सहायक समारोह और एक प्रक्रिया है जो एक-एक वस्तु को अलग 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 

प्रक्रिया ProcistListSQL प्रक्रिया के लिए कोड नीचे दिया गया है।

-- @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%)' 
संबंधित मुद्दे