Sql 其中一个存储过程出现故障
我有一个存储过程,在其中的一种情况下遇到了一些困难 如何在1个条件下编写这个,基本上如果我从和中删除所有内容,它就可以正常工作,但是我还想再添加一个条件,这样如果行的计数是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
>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