【问题标题】:How to write Dynamic SQL for this?如何为此编写动态 SQL?
【发布时间】:2011-09-03 15:59:57
【问题描述】:

我需要编写一个只执行语句的过程。

例子:

Create Procedure dbo.allSPExecute( @id int)
as
begin

EXEC dbo.tic @day= 7,@name = 'Gname',@Type = 'Utype'
EXEC dbo.tic @day= 7,@name = 'tname',@Type = 'Utype'
EXEC dbo.gtype @day = 7,@Tname = 'UName_By',@Udept = 'Dept'

End

我有 50 多个这样的语句。我有一个查找表:

ID  Name        SCol      Dcol       IOrd
1   dbo.tic     Gname     @name       1
1   dbo.tic     tname     @name       2
1   dbo.tic     Utype     @Type       1
1   dbo.tic     Utype     @Type       2
2   dbo.gtype   UName_By  @Tname      1
2   dbo.gtype   Dept      @Udept      1

有没有办法让如果我传递 ID,那么它将从查找表中获取值并执行该过程。有人可以帮忙吗?

编辑:更改查找表中的数据并创建过程

【问题讨论】:

    标签: sql sql-server sql-server-2008 stored-procedures dynamic-sql


    【解决方案1】:

    最简单的解决方案 - 使您的存储过程像这样:

    Create Procedure dbo.allSPExecute( @id int)
    as
    
    DECLARE @SQL varchar(max)
    
    SET @SQL = 'USE MyDB'
    
    SELECT @SQL = @SQL +
    'EXEC ' + t.Name + ' @day = 7,' + t.Dcol + ' = ''' + t.Scol + ''
    FROM MyTable t
    WHERE t.id = @ID
    
    EXEC (@SQL)
    

    【讨论】:

    • @JNK 请参考我的编辑问题。你给我的答案只有在我有一个参数时才有效,而不是在我有多个参数时
    • @Sam - 您编辑的标准毫无意义。关于哪些字段与哪些参数无关,没有押韵或理由。你需要给我更多的信息。我怎么知道id 1 的第三行作为第二个参数适用于其他行?
    • 离开@JNK 的回答,dbo.tic 的第 1、2 和 3 行之间的关系是什么?如果每一行都是对 proc 的调用,则此答案可以正常工作。您可能需要更改数据的存储方式,使其具有多个列来指定调用 proc 的参数。
    • @JNK 很抱歉没有提供足够的信息。我在表格中添加了另一列 Iord,因此我们可以确定。请参考我编辑的问题。再次为您的困惑感到抱歉
    • @Brent 请参考我编辑的问题
    【解决方案2】:

    这是一个不需要游标的解决方案。我正在使用 FOR XML 关键字将字符串连接在一起。我在两个地方这样做 - 一次用于连接参数列表,一次用于连接所有单独的 exec 语句。虽然我还没有测试过,但我认为这应该比使用游标快得多

    CREATE PROCEDURE dbo.allSPExecute( @id INT ) 
    AS  
    BEGIN   
      DECLARE @query VARCHAR(MAX);   
      SELECT @query =   (
        SELECT ExecPart + ' ' + SUBSTRING(Params,2,LEN(Params)) + CHAR(10)
        FROM
        (
          SELECT 
            ExecPart ='EXEC ' +(SELECT TOP 1 Name FROM MyTable WHERE ID = @id) ,
            Params = (SELECT ', ' + Dcol + ' = ' + Scol 
                      FROM MyTable t1 WHERE ID = @id AND t1.IOrd = t.IOrd FOR XML PATH(''))
          FROM MyTable t
          WHERE ID = @id
          GROUP BY IOrd
        ) t
        FOR XML PATH('')   
      ) 
    
      EXEC (@query) 
    END
    

    【讨论】:

    • 它工作正常,但如果我们有不同名称的相同 ID,它将无法工作。如果是这样,我们该怎么办?
    • 我已经使用光标解决了这个问题,现在它正在工作,非常感谢
    • 'Name' 是要执行的存储过程的名称吗?那么当您有两个不同名称的相同 ID 时,这意味着什么?这是否意味着您必须使用相同的参数一个接一个地执行两个存储的过程?
    【解决方案3】:

    这是一个从头开始编写且未经测试的光标示例:

    declare @dynsql as nvarchar(300)
    declare @tname as nvarchar(100)
    declare @tscol as nvarchar(100)
    declare @tdcol as nvarchar(100)
    
    set @dynsql = ''
    
    declare ticker as cursor for select Name, SCol, DCol from Lookup
    open ticker
    fetch next from ticker into @tname, @tscol, @tdcol
    
    while @@FETCH_STATUS = 0
    BEGIN
    
    set @dynsql = 'EXEC ' + @tname + ' @day=7, ' + @tdcol + '=''' + @tscol + ''''
    
    exec(@dynsql)
    
    FETCH NEXT from ticker into @tname, @tscol, @tdcol
    END
    
    close ticker
    deallocate ticker
    

    【讨论】:

      猜你喜欢
      • 2018-08-14
      • 2012-02-29
      • 1970-01-01
      • 1970-01-01
      • 2021-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多