Sql 其中一个存储过程出现故障

Sql 其中一个存储过程出现故障,sql,sql-server,sql-server-2008,stored-procedures,sql-server-2012,Sql,Sql Server,Sql Server 2008,Stored Procedures,Sql Server 2012,我有一个存储过程,在其中的一种情况下遇到了一些困难 如何在1个条件下编写这个,基本上如果我从和中删除所有内容,它就可以正常工作,但是我还想再添加一个条件,这样如果行的计数是>0,那么在循环中就只能这样了 如何做到这一点谁都不知道 这是我的实际SP: ALTER PROCEDURE [dbo].[USP_Insert__DDL_Records_Into_FinalTable] AS BEGIN DECLARE @DBName VARCHAR(50) DECLARE @SQLTableDet V

我有一个存储过程,在其中的一种情况下遇到了一些困难

如何在1个条件下编写这个,基本上如果我从中删除所有内容,它就可以正常工作,但是我还想再添加一个条件,这样如果行的计数是
>0
,那么在循环中就只能这样了

如何做到这一点谁都不知道

这是我的实际SP:

ALTER PROCEDURE [dbo].[USP_Insert__DDL_Records_Into_FinalTable]
AS 
BEGIN

DECLARE @DBName VARCHAR(50)
DECLARE @SQLTableDet VARCHAR(MAX)
DECLARE @SQLInsDet VARCHAR(MAX)
DECLARE @DelSQLTableDet VARCHAR(MAX)
DECLARE @Table_Name VARCHAR(20)
DECLARE @DestDB VARCHAR(20)

SET @DestDB = 'DB_Audit'
SET @Table_Name ='t_ddl_log'

DECLARE Database_Details CURSOR FOR 
SELECT name   
FROM 
sys.databases 
WHERE
database_id NOT IN (1,2,3,4) 
AND 
name <> 'DB_Audit' AND name <> 'DemoFatalCorruption1' AND name <>    'AdventureWorks' AND name <> 'AdventureWorks2008R2_Old' AND name <> 'AdventureWorks2008R2'

OPEN Database_Details

FETCH NEXT FROM Database_Details INTO @DBName

WHILE @@FETCH_STATUS = 0
BEGIN
IF (OBJECT_ID(+ @DBName + '.dbo.' + @Table_Name) IS NOT NULL) 

AND ('SELECT CAST (COUNT(*) AS varchar(20)) FROM ' + @DBName + '.dbo.' + @Table_Name) > '0'
BEGIN
    SET @SQLTableDet = ' INSERT INTO '+ @DestDB + '.dbo.'+ @Table_Name + 
                       ' SELECT * FROM ' + @DBName + '.dbo.' + @Table_Name   

    PRINT @SQLTableDet

    SET @SQLInsDet  = 'USE [' + @DBName + ']' + @SQLTableDet
    PRINT @SQLInsDet
    EXEC (@SQLInsDet)

    SET @DelSQLTableDet = 'DELETE FROM ' +  @DBName + '.dbo.' + @Table_Name 
    PRINT @DelSQLTableDet
    EXEC (@DelSQLTableDet)  
END     


FETCH NEXT FROM Database_Details INTO @DBName
PRINT @DBName

END  
CLOSE Database_Details  
DEALLOCATE Database_Details
END

其中,如果计数大于0,则仅向前移动,但如果移除If语句中的最后一个括号,则即使计数为0,循环内部也会发生一些变化

按如下方式更改IF语句的代码:

IF (OBJECT_ID(+ @DBName + '.dbo.' + @Table_Name) IS NOT NULL) 
AND ('SELECT CAST (COUNT(*) AS VARCHAR(20)) FROM ' + @DBName + '.dbo.' + 
@Table_Name) > 0

您可以将查询分成两部分

第一个
如果
检查表是否存在,第二个
如果检查基础表的任何行是否存在:

IF (OBJECT_ID(+ @DBName + '.dbo.' + @Table_Name) IS NOT NULL) 
    IF EXISTS ('SELECT * FROM ' + @DBName + '.dbo.' + @Table_Name)

您可以添加
开始
<代码>结束对于每个
如果
为更好的可读性,并且不会引起任何混乱。

可能有点长-但工作解决方案:

DECLARE @DBName varchar(50)
DECLARE @Table_Name varchar(50)
DECLARE @ConditionIsTrue BIT
DECLARE @SQL NVARCHAR(MAX)
SET @DBName = 'tempdb'
SET @Table_Name = 'MyTestTable'
SET @ConditionIsTrue = 0

SET @SQL = '
IF (OBJECT_ID(+ @DBName + ''.dbo.'' + @Table_Name) IS NOT NULL) 
    IF EXISTS (SELECT * FROM ' + @DBName + '.dbo.' + @Table_Name + ')
    SET @ConditionIsTrue = 1 '
Execute sp_executesql @SQL, N'@DBName VARCHAR(50), @Table_Name VARCHAR(50), @ConditionIsTrue BIT OUTPUT', @DBName, @Table_Name, @ConditionIsTrue OUTPUT
SELECT @ConditionIsTrue

您应该首先执行动态查询,然后检查其结果。 您应该使用
QuoteName
来避免sql注入

DECLARE @query nvarchar(max) = N'SELECT TOP 1 1 FROM ' + QuoteName(@DBName) + '.dbo.' + QuoteName(@Table_Name)

EXEC sp_executesql @query
DECLARE @RowCount int = @@ROWCOUNT


IF (
    OBJECT_ID(QuoteName(@DBName)  + '.dbo.' + QuoteName(@Table_Name)) IS NOT NULL 
    AND  @RowCount > 0
)
BEGIN
    -- Do stuff..........
END

即使很困难,它现在也没有给我任何错误,但它仍然在循环中,计数为0。现在是时候给我们提供更多关于您尝试执行的操作以及if语句后的代码的信息了。您期望的输出是什么?我正在创建一个用于审计的存储过程,其中,如果任何数据库有0个条目,则不应进入循环,因为这样会占用大量不必要的时间。因此,我试图做的是检查一个条件,如果计数大于0,则进入循环。它会给我一个错误“指定的非布尔类型的表达式”。
DECLARE @query nvarchar(max) = N'SELECT TOP 1 1 FROM ' + QuoteName(@DBName) + '.dbo.' + QuoteName(@Table_Name)

EXEC sp_executesql @query
DECLARE @RowCount int = @@ROWCOUNT


IF (
    OBJECT_ID(QuoteName(@DBName)  + '.dbo.' + QuoteName(@Table_Name)) IS NOT NULL 
    AND  @RowCount > 0
)
BEGIN
    -- Do stuff..........
END