动态 SQL 服务器查询
Dynamic SQL Server query
我正在存储过程中编写动态插入查询。我收到列名作为存储过程的参数。
例如,我有一个包含 EmployeeId
和 EmployeeName
列的 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);
我正在存储过程中编写动态插入查询。我收到列名作为存储过程的参数。
例如,我有一个包含 EmployeeId
和 EmployeeName
列的 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);