Tsql 如何对存储过程中的参数使用求值?

Tsql 如何对存储过程中的参数使用求值?,tsql,Tsql,我需要执行以下存储过程,其中@Table_temp应该是@Table和temp的串联。那么我如何正确地将其参数化呢 CREATE PROCEDURE [dbo].[swap_Collect] @Table varchar, @UniqueColumn varchar AS BEGIN IF (OBJECT_ID(@Table) IS NOT NULL ) BEGIN DECLARE @Table_temp as varchar SET @Ta

我需要执行以下存储过程,其中
@Table_temp
应该是
@Table
temp
的串联。那么我如何正确地将其参数化呢

CREATE PROCEDURE [dbo].[swap_Collect]
@Table  varchar,
@UniqueColumn varchar
AS

BEGIN
    IF (OBJECT_ID(@Table) IS NOT NULL )
    BEGIN
        DECLARE @Table_temp as varchar 
        SET @Table_temp= @Table + '_temp'
      DELETE FROM @Table where @UniqueColumn in (Select @UniqueColumn from @Table_temp)
      INSERT INTO @Table SELECT * from PRODUCTS_temp
      SELECT 1
    END
ELSE
    BEGIN 
      SELECT * INTO @Table from Collects_temp
      SELECT 1
    END
END

尽管有几种SQL方言支持,但SQL Server不支持变量作为对象名。您必须使用动态SQL解决这个问题

注释掉
EXEC
行,并取消注释
PRINT
行,以验证动态SQL是否正在生成适当的语句

我还注意到,所有
varchar
声明都缺少长度参数。这就是他们的全部,这当然不是你的本意。表名是使用
sysname
定义的,这与
NVARCHAR(128)
几乎相同,所以我切换到了它

CREATE PROCEDURE [dbo].[swap_Collect]
  @Table  varchar,
  @UniqueColumn varchar
AS

-- Moving the variable declaration so we can use them in both the IF and the ELSE
DECLARE @Table_temp as varchar = @Table + '_temp'
       ,@SQL varchar(500)
       ,@NL varchar(2) = CONCAT(CHAR(10),CHAR(13)); 
        -- This is a new line character to make the dynamic code more readable.

BEGIN
  IF (OBJECT_ID(@Table) IS NOT NULL ) --The variable is fine here.
    BEGIN

      -- Delete from the base table here.      
      SET @SQL = CONCAT(
        'DELETE FROM ',QUOTENAME(@Table), @NL,
        'WHERE ',QUOTENAME(@UniqueColumn),
        ' IN (SELECT ',QUOTENAME(@UniqueColumn),' FROM ', QUOTENAME(@Table_temp),');');
      --PRINT @SQL;
      EXEC sp_executesql @SQL;

      -- Insert into the base table here.
      SET @SQL = CONCAT(
        'INSERT INTO ', QUOTENAME(@Table), @NL,
        'SELECT * FROM ', QUOTENAME(@Table_temp),';');
      --PRINT @SQL;
      EXEC sp_executesql @SQL;

      SELECT 1
    END
  ELSE
      BEGIN 
        -- Insert into the base table here.
        -- SELECT...INTO only works if the target table doesn't exist. Since @Table does exist
        -- we'll use INSERT INTO instead. 
        SET @SQL = CONCAT(
          'INSERT INTO ', QUOTENAME(@Table), @NL,
          'SELECT * FROM ', QUOTENAME(@Table_temp),';');
        --PRINT @SQL;
        EXEC sp_executesql @SQL;

        SELECT 1
      END
END

因为它使用它,这里有一个很好的参考

尽管有几种SQL方言支持,但SQL Server不支持变量作为对象名。您必须使用动态SQL解决这个问题

注释掉
EXEC
行,并取消注释
PRINT
行,以验证动态SQL是否正在生成适当的语句

我还注意到,所有
varchar
声明都缺少长度参数。这就是他们的全部,这当然不是你的本意。表名是使用
sysname
定义的,这与
NVARCHAR(128)
几乎相同,所以我切换到了它

CREATE PROCEDURE [dbo].[swap_Collect]
  @Table  varchar,
  @UniqueColumn varchar
AS

-- Moving the variable declaration so we can use them in both the IF and the ELSE
DECLARE @Table_temp as varchar = @Table + '_temp'
       ,@SQL varchar(500)
       ,@NL varchar(2) = CONCAT(CHAR(10),CHAR(13)); 
        -- This is a new line character to make the dynamic code more readable.

BEGIN
  IF (OBJECT_ID(@Table) IS NOT NULL ) --The variable is fine here.
    BEGIN

      -- Delete from the base table here.      
      SET @SQL = CONCAT(
        'DELETE FROM ',QUOTENAME(@Table), @NL,
        'WHERE ',QUOTENAME(@UniqueColumn),
        ' IN (SELECT ',QUOTENAME(@UniqueColumn),' FROM ', QUOTENAME(@Table_temp),');');
      --PRINT @SQL;
      EXEC sp_executesql @SQL;

      -- Insert into the base table here.
      SET @SQL = CONCAT(
        'INSERT INTO ', QUOTENAME(@Table), @NL,
        'SELECT * FROM ', QUOTENAME(@Table_temp),';');
      --PRINT @SQL;
      EXEC sp_executesql @SQL;

      SELECT 1
    END
  ELSE
      BEGIN 
        -- Insert into the base table here.
        -- SELECT...INTO only works if the target table doesn't exist. Since @Table does exist
        -- we'll use INSERT INTO instead. 
        SET @SQL = CONCAT(
          'INSERT INTO ', QUOTENAME(@Table), @NL,
          'SELECT * FROM ', QUOTENAME(@Table_temp),';');
        --PRINT @SQL;
        EXEC sp_executesql @SQL;

        SELECT 1
      END
END

因为它使用它,这里有一个很好的参考

@MyTable
来自哪里?如果它是一个表变量,则不会声明它。如果它是一个表示表名的变量,则不会在任何位置为其赋值。它抱怨
@table
而不是
@MyTable
。我更正第二个参考。我需要表名作为输入参数@table的值,该参数被传递到存储过程
@MyTable
来自哪里?如果它是一个表变量,则不会声明它。如果它是一个表示表名的变量,则不会在任何位置为其赋值。它抱怨
@table
而不是
@MyTable
。我更正第二个参考。我需要表名作为输入参数@table的值,该参数被传递给存储过程