将 sp_executesql 的输出输入 table 列时出现问题(SQL 服务器)
Problem getting output of sp_executesql into a table column (SQL SERVER)
我有一个叫 QUERY_TABLE 的 table。
QUERY_TABLE 包含以下格式的查询(没有动态,WHERE 子句中的参数除外):
SELECT
CASE
WHEN COUNT(*) > 10 THEN 'Y'
ELSE 'N'
END check_ind
FROM
DATA_TABLE
WHERE date_y = @DATE_Y AND date_m = @DATE_M
我编写了以下脚本,以获取上述每个查询,运行,并将结果放入另一个 table - CONTROL_LOG_TABLE.
我的问题是结果列 STATUS_IND 应该得到 'Y' 或 'N' 作为值,但出于某种原因我还没有弄清楚,它包含 ' 0'.
感谢您的帮助!
DECLARE
@DATE_C DATE,
@DATE_Y INTEGER,
@DATE_M INTEGER,
@CHECK_NUM INTEGER,
@CHECK_ID INTEGER,
@CTRLM_TREE VARCHAR(50),
@CTRLM_TREE_PARAM VARCHAR(50),
@SQL_QUERY NVARCHAR(MAX),
@CHECK_DESC NVARCHAR(MAX),
@ACTION_DESC NVARCHAR(MAX),
@EXEC_SQL_QUERY NVARCHAR(MAX),
@RESULT_SQL CHAR(1),
@RowNo INTEGER,
@params NVARCHAR(100) = '@DATE_Y NVARCHAR(4), @DATE_M NVARCHAR(2)';
BEGIN
SET @RowNo = 0;
SET @DATE_C = GETDATE();
SET @DATE_Y = (SELECT YEAR (@DATE_C));
SET @DATE_M = (SELECT MONTH (@DATE_C));
DECLARE CURSOR_CHECK_ID CURSOR
FOR SELECT
CHECK_ID,
CTRLM_TREE,
SQL_QUERY,
CHECK_DESC,
ACTION_DESC
FROM
QUERY_TABLE
OPEN CURSOR_CHECK_ID;
FETCH NEXT FROM CURSOR_CHECK_ID INTO
@CHECK_ID,
@CTRLM_TREE,
@SQL_QUERY,
@CHECK_DESC,
@ACTION_DESC;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @RowNo = @RowNo+1
SET @CHECK_NUM = @RowNo
SET @EXEC_SQL_QUERY = @SQL_QUERY
EXECUTE @result_sql = sp_executesql @EXEC_SQL_QUERY, @params, @DATE_Y, @DATE_M
INSERT INTO CONTROL_LOG_TABLE (UPDATE_DATE, DATE_C, CHECK_NUM, CHECK_ID, CTRLM_TREE, SQL_QUERY,
CHECK_DESC, ACTION_DESC, STATUS_IND)
values (GETDATE(), @DATE_C, @RowNo, @CHECK_ID, @CTRLM_TREE, @SQL_QUERY, @CHECK_DESC, @ACTION_DESC, @RESULT_SQL)
FETCH NEXT FROM CURSOR_CHECK_ID INTO
@CHECK_ID,
@CTRLM_TREE,
@SQL_QUERY,
@CHECK_DESC,
@ACTION_DESC;
END;
CLOSE CURSOR_CHECK_ID;
DEALLOCATE CURSOR_CHECK_ID;
END;
要从动态批处理中捕获结果集,请使用 INSERT...EXECUTE 加载临时 table 或 table 变量。 EG
declare @r table (check_ind char(1))
insert into @r(check_ind)
EXECUTE sp_executesql @EXEC_SQL_QUERY, @params, @DATE_Y, @DATE_M
INSERT INTO CONTROL_LOG_TABLE (UPDATE_DATE, DATE_C, CHECK_NUM, CHECK_ID, CTRLM_TREE, SQL_QUERY,
CHECK_DESC, ACTION_DESC, STATUS_IND)
values (GETDATE(), @DATE_C, @RowNo, @CHECK_ID, @CTRLM_TREE, @SQL_QUERY, @CHECK_DESC, @ACTION_DESC, (select check_ind from @r) )
一种解决方案是将 INSERT
移动到动态查询中。
您不需要实际更改这些查询,您只需将 INSERT
连接起来即可。
SET @EXEC_SQL_QUERY = '
INSERT INTO CONTROL_LOG_TABLE (UPDATE_DATE, DATE_C, CHECK_NUM, CHECK_ID, CTRLM_TREE, SQL_QUERY,
CHECK_DESC, ACTION_DESC, STATUS_IND)
values (GETDATE(), @DATE_C, @RowNo, @CHECK_ID, @CTRLM_TREE, @SQL_QUERY, @CHECK_DESC, @ACTION_DESC, (' + @SQL_QUERY + ')';
';
另一种方法是将 SET @outputvariable
连接到它:
SET @EXEC_SQL_QUERY = 'SET @result = (' + @SQL_QUERY + ');
';
EXECUTE sp_executesql @EXEC_SQL_QUERY, @params, @DATE_Y, @DATE_M, @result_sql;
INSERT INTO CONTROL_LOG_TABLE (UPDATE_DATE, DATE_C, CHECK_NUM, CHECK_ID, CTRLM_TREE, SQL_QUERY,
CHECK_DESC, ACTION_DESC, STATUS_IND)
values (GETDATE(), @DATE_C, @RowNo, @CHECK_ID, @CTRLM_TREE, @SQL_QUERY, @CHECK_DESC, @ACTION_DESC, @RESULT_SQL)
并且您还需要将该输出参数添加到 @params
。
I'm assuming you have all your bases covered with SQL injection here.
我有一个叫 QUERY_TABLE 的 table。 QUERY_TABLE 包含以下格式的查询(没有动态,WHERE 子句中的参数除外):
SELECT
CASE
WHEN COUNT(*) > 10 THEN 'Y'
ELSE 'N'
END check_ind
FROM
DATA_TABLE
WHERE date_y = @DATE_Y AND date_m = @DATE_M
我编写了以下脚本,以获取上述每个查询,运行,并将结果放入另一个 table - CONTROL_LOG_TABLE.
我的问题是结果列 STATUS_IND 应该得到 'Y' 或 'N' 作为值,但出于某种原因我还没有弄清楚,它包含 ' 0'.
感谢您的帮助!
DECLARE
@DATE_C DATE,
@DATE_Y INTEGER,
@DATE_M INTEGER,
@CHECK_NUM INTEGER,
@CHECK_ID INTEGER,
@CTRLM_TREE VARCHAR(50),
@CTRLM_TREE_PARAM VARCHAR(50),
@SQL_QUERY NVARCHAR(MAX),
@CHECK_DESC NVARCHAR(MAX),
@ACTION_DESC NVARCHAR(MAX),
@EXEC_SQL_QUERY NVARCHAR(MAX),
@RESULT_SQL CHAR(1),
@RowNo INTEGER,
@params NVARCHAR(100) = '@DATE_Y NVARCHAR(4), @DATE_M NVARCHAR(2)';
BEGIN
SET @RowNo = 0;
SET @DATE_C = GETDATE();
SET @DATE_Y = (SELECT YEAR (@DATE_C));
SET @DATE_M = (SELECT MONTH (@DATE_C));
DECLARE CURSOR_CHECK_ID CURSOR
FOR SELECT
CHECK_ID,
CTRLM_TREE,
SQL_QUERY,
CHECK_DESC,
ACTION_DESC
FROM
QUERY_TABLE
OPEN CURSOR_CHECK_ID;
FETCH NEXT FROM CURSOR_CHECK_ID INTO
@CHECK_ID,
@CTRLM_TREE,
@SQL_QUERY,
@CHECK_DESC,
@ACTION_DESC;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @RowNo = @RowNo+1
SET @CHECK_NUM = @RowNo
SET @EXEC_SQL_QUERY = @SQL_QUERY
EXECUTE @result_sql = sp_executesql @EXEC_SQL_QUERY, @params, @DATE_Y, @DATE_M
INSERT INTO CONTROL_LOG_TABLE (UPDATE_DATE, DATE_C, CHECK_NUM, CHECK_ID, CTRLM_TREE, SQL_QUERY,
CHECK_DESC, ACTION_DESC, STATUS_IND)
values (GETDATE(), @DATE_C, @RowNo, @CHECK_ID, @CTRLM_TREE, @SQL_QUERY, @CHECK_DESC, @ACTION_DESC, @RESULT_SQL)
FETCH NEXT FROM CURSOR_CHECK_ID INTO
@CHECK_ID,
@CTRLM_TREE,
@SQL_QUERY,
@CHECK_DESC,
@ACTION_DESC;
END;
CLOSE CURSOR_CHECK_ID;
DEALLOCATE CURSOR_CHECK_ID;
END;
要从动态批处理中捕获结果集,请使用 INSERT...EXECUTE 加载临时 table 或 table 变量。 EG
declare @r table (check_ind char(1))
insert into @r(check_ind)
EXECUTE sp_executesql @EXEC_SQL_QUERY, @params, @DATE_Y, @DATE_M
INSERT INTO CONTROL_LOG_TABLE (UPDATE_DATE, DATE_C, CHECK_NUM, CHECK_ID, CTRLM_TREE, SQL_QUERY,
CHECK_DESC, ACTION_DESC, STATUS_IND)
values (GETDATE(), @DATE_C, @RowNo, @CHECK_ID, @CTRLM_TREE, @SQL_QUERY, @CHECK_DESC, @ACTION_DESC, (select check_ind from @r) )
一种解决方案是将 INSERT
移动到动态查询中。
您不需要实际更改这些查询,您只需将 INSERT
连接起来即可。
SET @EXEC_SQL_QUERY = '
INSERT INTO CONTROL_LOG_TABLE (UPDATE_DATE, DATE_C, CHECK_NUM, CHECK_ID, CTRLM_TREE, SQL_QUERY,
CHECK_DESC, ACTION_DESC, STATUS_IND)
values (GETDATE(), @DATE_C, @RowNo, @CHECK_ID, @CTRLM_TREE, @SQL_QUERY, @CHECK_DESC, @ACTION_DESC, (' + @SQL_QUERY + ')';
';
另一种方法是将 SET @outputvariable
连接到它:
SET @EXEC_SQL_QUERY = 'SET @result = (' + @SQL_QUERY + ');
';
EXECUTE sp_executesql @EXEC_SQL_QUERY, @params, @DATE_Y, @DATE_M, @result_sql;
INSERT INTO CONTROL_LOG_TABLE (UPDATE_DATE, DATE_C, CHECK_NUM, CHECK_ID, CTRLM_TREE, SQL_QUERY,
CHECK_DESC, ACTION_DESC, STATUS_IND)
values (GETDATE(), @DATE_C, @RowNo, @CHECK_ID, @CTRLM_TREE, @SQL_QUERY, @CHECK_DESC, @ACTION_DESC, @RESULT_SQL)
并且您还需要将该输出参数添加到 @params
。
I'm assuming you have all your bases covered with SQL injection here.