【问题标题】:What's wrong with the stored procedure存储过程有什么问题
【发布时间】:2014-01-02 11:52:33
【问题描述】:

我有一个名为Std_Components 的表,它的作用类似于具有关联表的组件列表的索引。 AssociatedTable 列包含实际包含组件数据的表的名称。

请检查下面的图片 -

这是Std_SteeringPumps的表格数据

我正在尝试创建一个存储过程,它将复制Std_Components 表以及所有具有新名称的关联表。例如。假设我为这个存储过程提供了 001 作为参数,我应该能够创建新表,如 C001_ComponentsC001_SteeringPumps 等。

这是我到目前为止所做的:

ALTER PROCEDURE [dbo].[sgi_sp_CreateTablesForNewCompany]
    -- Add the parameters for the stored procedure here
    @CompanyId varchar(5)
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

   -- declare variables
    declare @qry as varchar(2000)
    declare @compTblName as varchar(100)
    set @compTblName = 'C'+@companyId +'_Components'

    -- Check if table already exists
    IF object_id(@compTblName) is not null
        return

     -- Create main component index table by copying standard component table --
    set @qry = 'Select * into '+@compTblName+' From Std_Components;';
    --print @qry
    --execute (@qry)

    set @qry =@qry + 'Update C'+@companyId +'_Components Set AssociatedTable=''C'+@companyId +'''+substring(AssociatedTable,4,200);';
    --print @qry
    --exec @qry

    -- Create all child tables --
    Select * Into #TempTbl From dbo.Std_Components

    Declare @Id int

    While (Select Count(*) From #TempTbl) > 0
    Begin

        declare @rowTableName as varchar(50)
        declare @compNewTbl as varchar(50)

        Select Top 1 @rowTableName=AssociatedTable, @Id = Id From #TempTbl
        set @compNewTbl = 'C'+@companyId + substring(@rowTableName,4,200);

        set @qry = @qry + 'Select * into '+@compNewTbl+' From ' + @rowTableName + ';'
        --print @qry
        --exec @qry

        Delete #TempTbl Where Id = @Id

    End

    print @qry
    exec @qry
END

这是它生成的查询的打印语句的输出 -

Select * into C001_Components From Std_Components;
Update C001_Components Set AssociatedTable='C001'+substring(AssociatedTable,4,200);
Select * into C001_SteeringPumps From Std_SteeringPumps;

但是当执行存储过程时,我得到以下错误-

消息 203,级别 16,状态 2,过程 sgi_sp_CreateTablesForNewCompany,第 56 行
名称'Select * into C001_Components From Std_Components;Update C001_Components Set AssociatedTable='C001'+substring(AssociatedTable,4,200);Select * into C001_SteeringPumps From Std_SteeringPumps;'不是有效的标识符。

谁能帮我解决这个问题。

感谢您分享您的时间和智慧。

【问题讨论】:

    标签: sql-server-2008 stored-procedures


    【解决方案1】:

    您遇到的错误是因为 EXEC 语句(存储过程的最后一行)需要在 @qry 变量周围加上括号,以便它变为

    执行(@qry)

    没有括号,它将整个 SQL 字符串视为存储过程名称。

    【讨论】:

      【解决方案2】:

      无效的标识符在 AssociatedTable 部分周围

      Set AssociatedTable='C001'+substring(AssociatedTable,4,200); 不会运行,因为 AssociatedTable 没有子字符串的范围 - 字符串需要完全包含表的名称才能执行

      【讨论】:

        【解决方案3】:

        代替

        exec @qry;
        

        你需要

        exec sp_executesql @qry;
        

        您还需要将@qry 的类型更改为NVARCHAR。请注意,由于是动态 sql,proc 容易出现 SQL Injection 和其他转义问题(即确保 @CompanyId 已验证)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-04-23
          • 1970-01-01
          • 2018-09-20
          相关资源
          最近更新 更多