动态 SQL 服务器查询

Dynamic SQL Server query

我正在存储过程中编写动态插入查询。我收到列名作为存储过程的参数。

例如,我有一个包含 EmployeeIdEmployeeName 列的 Employee table。我需要在每个员工姓名前附加 EMP_,同时将数据从 Employee table.

插入 Department table

非动态查询如下所示。

 INSERT INTO Department(EmployeeId, EmployeeName)
     SELECT 
         EmployeeId, 'EMP_' + EmployeeName
     FROM 
         Employee

如果我写动态插入

 SET @SqlCommand =
          'INSERT INTO ' + @DepartmentTable + '(' + @EmployeeIdColumn + ',' + @EmployeeNameColumn + ')' +
          'SELECT ' + @EmployeeIdColumn + ',''EMP_''' + @EmployeeNameColumn + '''' +     
          'FROM ' +
              @EmployeeTable + ' WTB '  

        EXEC sp_executesql
        @stmt        = @SqlCommand 

问题是,对于 EmployeeName 列,它插入的是 "EMP_EmployeeName" 而不是实际的员工姓名。我尝试在 EmployeeNameColumn 前后加上引号,但没有用。我该如何解决?

尝试使用 CONCAT 函数。

-- Syntax for SQL Server, Azure SQL Database, Azure SQL Data Warehouse, Parallel Data Warehouse  

CONCAT ( string_value1, string_value2 [, string_valueN ] )  

您的查询将如下所示:

INSERT INTO deptTable(empId,empName) 
SELECT empId,concat('EMP_', empName) as empName FROM empTable

PS:看来我误解了你的问题。

INSERT INTO deptTable(empId,empName) 
SELECT empId,'SUFFIX'+empName as empName FROM empTable

也可以。我猜你想要它用于存储过程。

在任何情况下 concat 仍然应该这样做。

EMP_'' 之后只需要一个 +,在 ' WTB ' 之后将其删除。我还修复了一些空格:

SET @SqlCommand =
'INSERT INTO ' + @DepartmentTable + ' (' + @EmployeeIdColumn + ',' + @EmployeeNameColumn + ')' +
' SELECT ' + @EmployeeIdColumn + ',''EMP_''+' + @EmployeeNameColumn +      
' FROM ' + @EmployeeTable + ' WTB ' 

如果你PRINT @SqlCommand你会得到这样的东西:

INSERT INTO Department (EmpId,EmpName) SELECT EmpId,'EMP_'+EmpName FROM Employee WTB 

还有一个注意事项:最好将 QUOTENAME 与 table/column 名称一起使用。这将有助于避免列名称中包含空格的情况,例如 'Employee Name':

SET @SqlCommand =
'INSERT INTO ' + QUOTENAME(@DepartmentTable) + '(' + QUOTENAME(@EmployeeIdColumn) + ',' + QUOTENAME(@EmployeeNameColumn) + ')'+
' SELECT ' + QUOTENAME(@EmployeeIdColumn) + ',''EMP_''+' + QUOTENAME(@EmployeeNameColumn) + 
' FROM ' + QUOTENAME(@EmployeeTable) + ' WTB '

获得:

INSERT INTO [Department]([EmpId],[EmpName]) SELECT [EmpId],'EMP_'+[EmpName] FROM [Employee] WTB 

这里是创建存储过程的动态查询 insert 带有列和参数的语句

> DECLARE @table_name varchar(255) = 'table_name'
>       DECLARE @v_col varchar(MAX)
>       DECLARE @v_param varchar(MAX)
>       DECLARE @SP_param varchar(MAX)
>       DECLARE @sp_type varchar(10) = 'Insert'
>     
>         SET @v_col = STUFF(
>                      (SELECT ',' + '['+c.name+']'
>                      FROM sys.tables t  JOIN sys.columns c ON t.object_id = c.object_id
>                                 WHERE t.name = @table_name
>                                 AND c.is_identity = 0
>                          FOR XML PATH ('')), 1, 1, ''
>                             )
>         SET @v_param =  STUFF(
>                          (SELECT ',' + '@'+c.name
>                          FROM sys.tables t  JOIN sys.columns c ON t.object_id = c.object_id
>                                 WHERE t.name = @table_name
>                                 AND c.is_identity = 0
>                          FOR XML PATH ('')), 1, 1, ''
>                             )
>     
>         SET @SP_param = STUFF(
>                          (SELECT ',' + '@'+c.name+' '+y.name+' '+(CASE WHEN y.name = 'varchar' THEN '('+CAST(c.max_length as varchar)+')'
> ELSE '' END)
>                          FROM sys.tables t  JOIN sys.columns c ON t.object_id = c.object_id
>                          JOIN sys.types y ON y.user_type_id = c.user_type_id
>                                 WHERE t.name = @table_name
>                                 AND c.is_identity = 0
>                          FOR XML PATH ('')), 1, 1, ''
>                             )
>       Declare @Query VARCHAR(MAX)
>       DECLARE @SPQuery VARCHAR(MAX)
>       SET @SPQuery = 'CREATE PROCEDURE '+@sp_type+''+@table_name+' ('+@SP_param+')
>       AS BEGIN'
>       SET @Query='Insert Into '+@table_name+' ('+@v_col+')
>         Values (
>             '+@v_param+')
>             END'
>     
>     
>       PRINT(@SPQuery); 
>       PRINT(@Query);