【问题标题】:Create SQL procedures in while-loop with procedure-name as variable在 while 循环中创建 SQL 过程,过程名称为变量
【发布时间】:2015-05-28 21:41:06
【问题描述】:

有没有办法通过 SQL 中的 while 循环创建过程列表?

我试图做的是这样的事情,但属性表要大得多。

Declare @attributes Table (attrkey text, attr_key text)
  Insert @attributes(attrkey, attr_key) values('userFirstName',  'user_first_name')
  Insert @attributes(attrkey, attr_key) values('userFamilyName', 'user_family_name')
  Insert @attributes(attrkey, attr_key) values('userNameExtra',  'user_name_extra')

Declare @attrkey nvarchar(128)
Declare @attr_key nvarchar(128)
Declare @proc_name_set nvarchar(128)
Declare @proc_name_del nvarchar(128)


While exists (Select * From @attributes)
  Begin
    Select @attrkey = attrkey, @attr_key = attr_key from @attributes
    Set @proc_name_set = 'set_web_user_' + @attr_key
    Set @proc_name_del = 'del_web_user_' + @attr_key

    CREATE PROCEDURE [dbo].[@proc_name_set] @keyval int, @value nvarchar(255)  AS
    UPDATE web_user SET @attrkey=@value WHERE id=@keyval;
    Go
    CREATE PROCEDURE [dbo].[@proc_name_del] @keyval int, @value nvarchar(255)  AS
    UPDATE web_user SET @attrkey=NULL WHERE id=@keyval AND @attrkey=@value;
    Go

    Delete from @attributes where attrkey like @attrkey
  End

【问题讨论】:

  • 为特定语言添加标签。 mysql,oracle,ms sql,postgres ...根据您的问题。您可以使用动态 sql 来做到这一点。在普通的 sql 中没有办法做到这一点
  • 你不应该使用这样的变量,应该将其分配给其他变量(let as @sql)并使用 exec 或执行它sp_execute sql 作为 EXEC(@sql)
  • 如果您的循环构建了一个包含 CREATE PROCEDURE 语句的字符串,您可能会更开心,使用 sp_execute_sql 运行该动态 sql。但我以前从未尝试从一个过程中创建一个过程。对我来说,这感觉像是一种破碎的设计模式。为什么要这样做,功能要求是什么?
  • 您的意思是将创建部分存储在字符串中而不是使用 EXEC?
  • 不能创建一个以属性为参数的SP吗?

标签: sql sql-server tsql procedure


【解决方案1】:

虽然可能有更好的方法可以做到这一点,但我想这可能是一次性操作,性能可能并不重要。如果是这样,那么修改后的代码应该可以工作并为所有属性创建一个set_web_user_del_web_user_ 过程:

Declare @attributes Table (attrkey text, attr_key text)
Insert @attributes(attrkey, attr_key) values('userFirstName',  'user_first_name')
Insert @attributes(attrkey, attr_key) values('userFamilyName', 'user_family_name')
Insert @attributes(attrkey, attr_key) values('userNameExtra',  'user_name_extra')

Declare @attrkey nvarchar(128)
Declare @attr_key nvarchar(128)
Declare @proc_name_set nvarchar(128)
Declare @proc_name_del nvarchar(128)
Declare @proc_text nvarchar(max)

While exists (Select * From @attributes)
  Begin
    Select @attrkey = attrkey, @attr_key = attr_key from @attributes
    Set @proc_name_set = 'set_web_user_' + @attr_key
    Set @proc_name_del = 'del_web_user_' + @attr_key

    Set @proc_text = N'CREATE PROCEDURE [dbo].[' + @proc_name_set + '] @keyval int, @value nvarchar(255)  AS
    UPDATE web_user SET ' + @attrkey + ' = @value WHERE id = @keyval;'

    EXEC sp_executesql @proc_text

    Set @proc_text = N'CREATE PROCEDURE [dbo].[' + @proc_name_del + '] @keyval int, @value nvarchar(255)  AS
    UPDATE web_user SET ' + @attrkey + ' = NULL WHERE id = @keyval AND ' + @attrkey + ' = @value;'

    EXEC sp_executesql @proc_text

    Delete from @attributes where attrkey like @attrkey
  End

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-28
    • 1970-01-01
    • 2011-03-05
    • 2017-09-21
    • 1970-01-01
    相关资源
    最近更新 更多