Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Debugging 在MS sql Server 2008中调试动态sql+动态表_Debugging_Sql Server 2008_Dynamic Sql_Dynamic Tables - Fatal编程技术网

Debugging 在MS sql Server 2008中调试动态sql+动态表

Debugging 在MS sql Server 2008中调试动态sql+动态表,debugging,sql-server-2008,dynamic-sql,dynamic-tables,Debugging,Sql Server 2008,Dynamic Sql,Dynamic Tables,我有一个混乱的存储过程,它使用动态sql 我可以通过添加print@sql在运行时调试它;其中@sql;是包含动态SQL的字符串,就在我调用execute@SQL;之前 现在,多页存储过程还创建动态表并在查询中使用它们。我想在执行execute之前将这些表打印到控制台,这样我就可以确切地知道查询要做什么 但是,SQLServer08不喜欢这样。当我尝试时: 打印温度表;并尝试编译S.P.我得到以下错误: 在此上下文中不允许使用名称temp_table。有效表达式包括常量、常量表达式以及某些上下文

我有一个混乱的存储过程,它使用动态sql

我可以通过添加print@sql在运行时调试它;其中@sql;是包含动态SQL的字符串,就在我调用execute@SQL;之前

现在,多页存储过程还创建动态表并在查询中使用它们。我想在执行execute之前将这些表打印到控制台,这样我就可以确切地知道查询要做什么

但是,SQLServer08不喜欢这样。当我尝试时:

打印温度表;并尝试编译S.P.我得到以下错误:

在此上下文中不允许使用名称temp_table。有效表达式包括常量、常量表达式以及某些上下文中的变量。不允许使用列名

请帮忙

编辑:

说到SQL,我是个傻瓜。但是,下面的语句是:select*from tbl;当控制台以非交互方式运行时,不会将任何内容打印到控制台;不过,print语句仍然有效

以下语句的语法不正确:print select*from tbl;。如果stdout不是一个选项,有没有办法将select的输出重定向到一个文件


谢谢。

通过这种方式调试您将获得输出的唯一方法是

select * from #temp_table;
或者,查看SQL Server Management Studio中内置的调试功能。例如,此网页可能对您有所帮助


通过这种方式进行调试获得输出的唯一方法是

select * from #temp_table;
或者,查看SQL Server Management Studio中内置的调试功能。例如,此网页可能对您有所帮助


可以打印变量,但不能打印表。但是,您可以从表中进行选择

现在,如果在执行的单个语句中创建、填充和修改表,那么您可以查看表的状态,就像修改前一样,但数据将在修改后发生更改

当然,一旦动态sql完成,表就不再可用,所以您就被卡住了


为了解决这个问题,您可以将动态SQL中的双哈希标记与表一起插入到表中,然后在动态SQL执行结束时查询该表。

您可以打印变量,但不能打印表。但是,您可以从表中进行选择

现在,如果在执行的单个语句中创建、填充和修改表,那么您可以查看表的状态,就像修改前一样,但数据将在修改后发生更改

当然,一旦动态sql完成,表就不再可用,所以您就被卡住了


要解决这个问题,您可以将动态SQL中的双哈希标记与表一起插入到表中,然后在动态SQL执行结束时查询该表。

对于我最讨厌的游标,请尝试一下:

SET NOCOUNT ON
CREATE TABLE #TempTable1
(ColumnInt      int        
,ColumnVarchar  varchar(50)
,ColumnDatetime datetime   
)
INSERT INTO #TempTable1 VALUES (1,'A',GETDATE())
INSERT INTO #TempTable1 VALUES (12345,'abcdefghijklmnop','1/1/2010')
INSERT INTO #TempTable1 VALUES (null,null,null)
INSERT INTO #TempTable1 VALUES (445454,null,getdate())
SET NOCOUNT OFF

DECLARE @F_ColumnInt      int
       ,@F_ColumnVarchar  varchar(50)
       ,@F_ColumnDatetime datetime

DECLARE CursorTempTable1 CURSOR FOR
    SELECT
        ColumnInt, ColumnVarchar, ColumnDatetime
    FROM #TempTable1
    ORDER BY ColumnInt
    FOR READ ONLY

--populate and allocate resources to the cursor
OPEN CursorTempTable1

PRINT '#TempTable1 contents:'
PRINT '    '+REPLICATE('-',20)
       +'  '+REPLICATE('-',50)
       +'  '+REPLICATE('-',23)

--process each row
WHILE 1=1
BEGIN

    FETCH NEXT FROM CursorTempTable1
        INTO @F_ColumnInt, @F_ColumnVarchar, @F_ColumnDatetime

    --finished fetching all rows?
    IF @@FETCH_STATUS <> 0
    BEGIN --YES, all done fetching
        --exith the loop
        BREAK
    END --IF finished fetching

    PRINT '    '+RIGHT(   REPLICATE(' ',20)   +   COALESCE(CONVERT(varchar(20),@F_ColumnInt),'null')                               ,20)
           +'  '+LEFT(                            COALESCE(@F_ColumnVarchar,'null')                        +   REPLICATE(' ',50)   ,50)
           +'  '+LEFT(                            COALESCE(CONVERT(char(23),@F_ColumnDatetime,121),'null') +   REPLICATE(' ',23)   ,23)

END --WHILE

--close and free the cursor's resources
CLOSE CursorTempTable1
DEALLOCATE CursorTempTable1

如果我知道您的临时表有一个PK,我会给出一个无游标循环的示例。

尽管我讨厌游标,但请尝试一下:

SET NOCOUNT ON
CREATE TABLE #TempTable1
(ColumnInt      int        
,ColumnVarchar  varchar(50)
,ColumnDatetime datetime   
)
INSERT INTO #TempTable1 VALUES (1,'A',GETDATE())
INSERT INTO #TempTable1 VALUES (12345,'abcdefghijklmnop','1/1/2010')
INSERT INTO #TempTable1 VALUES (null,null,null)
INSERT INTO #TempTable1 VALUES (445454,null,getdate())
SET NOCOUNT OFF

DECLARE @F_ColumnInt      int
       ,@F_ColumnVarchar  varchar(50)
       ,@F_ColumnDatetime datetime

DECLARE CursorTempTable1 CURSOR FOR
    SELECT
        ColumnInt, ColumnVarchar, ColumnDatetime
    FROM #TempTable1
    ORDER BY ColumnInt
    FOR READ ONLY

--populate and allocate resources to the cursor
OPEN CursorTempTable1

PRINT '#TempTable1 contents:'
PRINT '    '+REPLICATE('-',20)
       +'  '+REPLICATE('-',50)
       +'  '+REPLICATE('-',23)

--process each row
WHILE 1=1
BEGIN

    FETCH NEXT FROM CursorTempTable1
        INTO @F_ColumnInt, @F_ColumnVarchar, @F_ColumnDatetime

    --finished fetching all rows?
    IF @@FETCH_STATUS <> 0
    BEGIN --YES, all done fetching
        --exith the loop
        BREAK
    END --IF finished fetching

    PRINT '    '+RIGHT(   REPLICATE(' ',20)   +   COALESCE(CONVERT(varchar(20),@F_ColumnInt),'null')                               ,20)
           +'  '+LEFT(                            COALESCE(@F_ColumnVarchar,'null')                        +   REPLICATE(' ',50)   ,50)
           +'  '+LEFT(                            COALESCE(CONVERT(char(23),@F_ColumnDatetime,121),'null') +   REPLICATE(' ',23)   ,23)

END --WHILE

--close and free the cursor's resources
CLOSE CursorTempTable1
DEALLOCATE CursorTempTable1

如果我知道您的临时表有一个PK,我会给出一个无游标循环示例。

当我们使用动态SQl时,我们首先在sp中设置一个调试输入变量,使其成为最后一个变量,并将其默认值设置为0,以指示不处于调试模式,这样它就不会中断调用proc的现有代码


现在,当您在调试模式下运行它时,您可以打印而不是执行,或者打印并执行,但最后总是回滚。如果您需要查看各个阶段的数据,最好的做法是第二步。然后在回滚之前,将要查看的数据放入一个表变量中,这很重要,它不能是临时表。在回滚之后,从没有超出回滚范围的表变量中进行选择,然后运行print TStations以查看运行的查询。

当我们使用动态SQl时,我们首先在sp中设置一个调试输入变量,使其成为最后一个变量,并将其默认值设置为0,以指示未处于调试模式,这样它不会中断现有代码调用进程


现在,当您在调试模式下运行它时,您可以打印而不是执行,或者打印并执行,但最后总是回滚。如果您需要查看各个阶段的数据,最好的做法是第二步。然后在回滚之前,将要查看的数据放入一个表变量中,这很重要,它不能是临时表。回滚后,从没有超出回滚范围的表变量中选择,然后运行print TStations以查看已运行的查询。

但会打印到控制台吗?如果这是我正在执行的唯一语句,它就会执行。事实上,我刚刚试过——它什么也不打印。打印@sql;语句仍然有效。SP将输出每个不在别处的select,例如作为insert或@variable的一部分update@CResults,请你详细说明一下好吗?我不确定我是否理解了这个评论。例如,创建proc MyProc作为Select*from MyTable;硒

从MyTable中选择*;SP将向您输出两个记录集。打印@sql将起作用,因为@sql是一个字符串。temp_表不是,它是一个记录集。@C结果:动态sql有问题。它返回:Msg 4104,级别16,状态1,第1行多部分标识符X.Y无法绑定。我正试图调试一个糟糕的连接。这是一个第22条军规——在调试它之前,程序需要正确执行:我需要在400行SQL中进行一个小的修复,因此要去掉导致错误的部分并使用二进制搜索/除法n征服并不是那么容易。真正有帮助的是将一个表转换成字符串并打印出来的能力。但这会打印到控制台吗?如果这是我正在执行的唯一语句,它就会执行。事实上,我刚刚试过——它什么也不打印。打印@sql;语句仍然有效。SP将输出每个不在别处的select,例如作为insert或@variable的一部分update@CResults,请你详细说明一下好吗?我不确定我是否理解了这个评论。例如,创建proc MyProc作为Select*from MyTable;从MyTable中选择*;SP将向您输出两个记录集。打印@sql将起作用,因为@sql是一个字符串。temp_表不是,它是一个记录集。@C结果:动态sql有问题。它返回:Msg 4104,级别16,状态1,第1行多部分标识符X.Y无法绑定。我正试图调试一个糟糕的连接。这是一个第22条军规——在调试它之前,程序需要正确执行:我需要在400行SQL中进行一个小的修复,因此要去掉导致错误的部分并使用二进制搜索/除法n征服并不是那么容易。真正有帮助的是将表转换成字符串并打印出来的能力。@Raj,它实际上是静态和动态sql的混合体,所以动态表是在使用它的动态sql拼凑在一起之前创建的。我的问题仍然是:如何将选择的结果打印到控制台、文件等?@Hamish,如果您执行的选择将打印到控制台。@Raj,它实际上是静态和动态sql的混合体,因此动态表是在使用它的动态sql修补到一起之前创建的。我的问题仍然是:如何将选择的结果打印到控制台、文件等?@Hamish,如果您执行的选择将打印到控制台。@KM,如果您要创建一个光标,最好创建一个Cursor@Raj更多如果我知道所讨论的表的PK结构,我可以编写一个无游标的循环,如下所示:但是这个游标对于OP来说是通用的,足以让代码正常工作。什么是光标?@KM光标就像一个临时表。仅适用于当前连接。@KM,如果要创建光标,最好创建一个Cursor@Raj此外,如果我知道所讨论的表的PK结构,我可以编写一个无游标循环,如下所示:但是这个游标对于OP来说足够通用,可以让代码正常工作。什么是光标?@KM光标就像一个临时表。仅适用于当前连接。