【问题标题】:Trouble in one of the stored procedure存储过程之一出现问题
【发布时间】:2017-06-23 06:58:23
【问题描述】:

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

如何在 1 个条件下写这个,基本上如果我从 AND 中删除所有内容,它工作正常,但我还想再添加一个条件,以便如果行数为 > 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

我在这条线下有个问题

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

其中如果计数大于0,则仅向前移动,但是即使计数为0,它也会进入循环内部

【问题讨论】:

    标签: sql sql-server sql-server-2008 stored-procedures sql-server-2012


    【解决方案1】:

    您可以将查询一分为二。

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

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

    您可以为每个IF 添加BEGIN ... END 以获得更好的可读性并且不会引起任何混淆。

    【讨论】:

    • 它给了我一个错误“指定非布尔类型的表达式。
    【解决方案2】:

    您应该先执行动态查询,然后检查其结果。 你应该使用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
    

    【讨论】:

      【解决方案3】:

      这可能有点冗长 - 但可行的解决方案:

      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
      

      【讨论】:

        【解决方案4】:

        删除 IF 语句中的最后一个括号将解决您的问题。

        修改IF语句的代码如下:

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

        【讨论】:

        • 即使很难,它现在也没有给我任何错误,但它仍然在计数为 0 的循环内
        • 现在是时候向我们提供更多信息,了解您正在尝试做什么以及 if 语句之后的代码。您的预期输出是什么?
        • 我正在为 Audit 创建一个存储过程,其中如果任何数据库有 0 个条目,它不应该进入循环,因为这样会花费大量不必要的时间。所以我想做的是我检查一个条件,如果计数大于 0,然后进入循环
        猜你喜欢
        • 1970-01-01
        • 2019-02-28
        • 1970-01-01
        • 2021-06-14
        • 2020-09-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-26
        相关资源
        最近更新 更多