0

我有一個存儲過程,其中我在一種情況下遇到了一些困難。存儲過程之一中的問題

如何寫這個在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 

而且我有一個問題,這條線

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,也會進入循環內部

回答

0

刪除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

即使辛苦也沒有給我任何錯誤了,但它仍然是環路,將計數爲0 –

+0

現在是時候給我們介紹一下你正在嘗試做的和多一點信息裏面去if語句之後的代碼。你的預期產出是多少? –

+0

我正在爲審計創建一個存儲過程,其中如果任何數據庫有0個條目,它不應該進入循環,因爲那樣會花費大量不必要的時間。所以我試圖做的是我檢查一個條件,如果計數大於0,然後進入循環 –

1

您可以查詢一分爲二。

第一IF檢查表存在和第二IF檢查任何行生存的基礎表:

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

您可以添加BEGIN ... END每個IF更好的可讀性並不會造成任何混淆。

+0

它給了我一個錯誤「一個非布爾類型指定的表達式。 –

0

可能這是一個有點冗長 - 但工作液:

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 
0

你應該先執行動態查詢,然後檢查其結果。 您應該使用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