Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-cloud-platform/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
Sql server 使用游标,如何处理SQL中的错误_Sql Server_Tsql_Try Catch_Database Cursor - Fatal编程技术网

Sql server 使用游标,如何处理SQL中的错误

Sql server 使用游标,如何处理SQL中的错误,sql-server,tsql,try-catch,database-cursor,Sql Server,Tsql,Try Catch,Database Cursor,我有多个数据库,我在其中寻找一个名为“国家”的专栏。如果列存在,则检查列中的空格字符。如果我循环遍历一个游标,没有Countries列的DB将抛出一个错误。我如何处理这个错误 问题:挡块未处理,请帮助我解决问题 查询如下所示 CREATE PROCEDURE [dbo].[USP_SMSGeneric_CountrySpace] @DB VARCHAR(100) As

我有多个数据库,我在其中寻找一个名为“国家”的专栏。如果列存在,则检查列中的空格字符。如果我循环遍历一个游标,没有Countries列的DB将抛出一个错误。我如何处理这个错误

问题:挡块未处理,请帮助我解决问题

查询如下所示

CREATE PROCEDURE [dbo].[USP_SMSGeneric_CountrySpace] @DB VARCHAR(100)                                        
As                                        
BEGIN                                        

SET NOCOUNT ON                                    

DECLARE @StudyID  varchar(max)                                    
DECLARE @Databasename VARCHAR(max)                                    
DECLARE @QUERY NVARCHAR(MAX)                                  
DECLARE @Protocol varchar(max)                                    
DECLARE @Servername varchar(max)                                     
DECLARE @script VARCHAR(Max)        
DECLARE @script1 VARCHAR(Max)                                    
DECLARE @initscript NVARCHAR(Max)       
DECLARE @Countries VARCHAR(Max)         
DECLARE @Countryrelease VARCHAR(Max) 

IF OBJECT_ID('TEMPDB..#OBJMISSING') IS NOT NULL DROP TABLE  #OBJMISSING       


CREATE TABLE #OBJMISSING (ERRID INT IDENTITY(1,1),ERRNUM BIGINT,ERRMSG VARCHAR(MAX),DBNAME VARCHAR(MAX))                                        


SET @initscript='
    DECLARE csrStudy CURSOR FOR                                    
    SELECT  ProtocolName, DBName, studyid,DBServer AS Servername from SMSAPP.dbo.studymaster  WITH (NOLOCK)                                   
      WHERE ClientName LIKE ''%NOVARTIS%'' AND studystatus IN (1,2) AND DBServer  IN (''SQL002'' ,''SQL004'',''SQL005'')                                         
    '
EXEC sp_executesql @initscript                                 

OPEN csrStudy                                  
FETCH NEXT FROM csrStudy INTO @Protocol,@Databasename,@StudyID,@ServerName                                    

WHILE @@FETCH_STATUS = 0                                      
BEGIN                                      
    SET @DB = @Servername+'.'+@Databasename        

    SET @script = '

    DECLARE @StrValue VARCHAR(max)

    BEGIN TRY     
        IF EXISTS (         
            SELECT DISTINCT 1 FROM  '+@DB+'.sys.columns c JOIN '+@DB+'.sys.Tables t ON c.Object_ID=t.Object_ID
            WHERE c.Name = ''Countries’'' AND t.name =''tblMaterials'')      
        BEGIN
            SELECT  @StrValue = ISNULL(@StrValue + '','', '''') + Countries’ FROM (
            SELECT DISTINCT (LEN(Countries’ + '','') - LEN(REPLACE(Countries’, '' '', '''') + '',''))CNT,Countries  
            FROM  '+@DB+'.dbo.tblMaterials WITH (NOLOCK) )A WHERE CNT>0
        END
    END TRY

    BEGIN CATCH          
        INSERT INTO #OBJMISSING VALUES 
        (ERROR_NUMBER(),ERROR_MESSAGE(),''+@Databasename+'')     
    END CATCH     

    IF @StrValue IS NOT NULL   -- If any Duplicate values found, then raise an alert           
    BEGIN           
        SELECT '+@StudyID+' As StudyID,
        ''Countries field value Should not have space''   AS Actual ,          
        ''Countries field value exists with space for String :'' + @StrValue AS Discrepancy INTO #tempOutput       
我得到以下错误:

链接服务器“SQL001”的OLE DB提供程序“SQLNCLI10”不可用 包含表“RAW.”dbo.“tblMaterials”。该表 不存在或当前用户没有该表的权限


您需要一个
TRY-CATCH
动态SQL外部

显示的错误消息在parse时间,甚至在执行之前(对于该
EXEC
语句)。此时,引擎验证表和对象是否存在,如果不存在,则返回错误。执行从未开始,因此它将永远不会到达
CATCH
部分。这就是为什么
TRY CATCH
需要在动态SQL之外,因为整个动态SQL在解析后将被拒绝


您收到的错误消息来自如下查询:

EXEC('SELECT * FROM [SomeLinkedServer].DatabaseName.SchemaName.NonExistingTable')
Msg 7314,级别16,状态1,第1行OLE DB提供程序“SQLNCLI11” 对于链接服务器,“SomeLinkedServer”不包含表 “数据库名”“SchemaName”“不存在表”“。表不存在或不存在。” 当前用户没有该表的权限

如果您可以将其包装到一个
TRY CATCH
,那么控制流将跳转到CATCH,因为错误的严重性足够高:

BEGIN TRY

    EXEC('SELECT * FROM [SomeLinkedServer].DatabaseName.SchemaName.NonExistingTable')

END TRY

BEGIN CATCH

    SELECT 'This is the catch section'

END CATCH

请注意,在没有动态SQL的情况下,与以下示例的区别:

BEGIN TRY

    SELECT 1 FROM [SomeLinkedServer].DatabaseName.SchemaName.NonExistingTable

END TRY

BEGIN CATCH

    SELECT 1

END CATCH
Msg 208,16级,状态1,第3行无效对象名称 “DatabaseName.SchemaName.NonExistingTable”

这是因为整个批处理在解析后被拒绝,因此它无法跳转到
捕获
,因为它从未开始执行。当使用动态SQL时,动态部分的解析、编译和执行发生在
EXEC
点(这正是它是动态的原因),延迟错误抛出以便捕获它


我无法提供完整的修复代码,因为您发布的内容不完整。但如果遵循以下准则,您应该能够忽略错误:

DECLARE @Variable ...

DECLARE MyCursor CURSOR FOR ...

FETCH NEXT FROM MyCursor INTO @Variable

WHILE @@FETCH_STATUS = 0
BEGIN

    BEGIN TRY

        DECLARE @DynamicSQL VARCHAR(MAX) = ... -- The DynamicSQL may have another TRY CATCH inside

        EXEC(@DynamicSQL)

    END TRY

    BEGIN CATCH

        -- Do your catch operation here, you can leave this section empty if you want (not recommended)

    END CATCH

    FETCH NEXT FROM MyCursor INTO @Variable

END

我建议您首先在动态sql之外使用try-catch“没用,你能描述一下出错时会发生什么吗?非常感谢你的解释,这对我很有用。。。请让我知道在我上面的查询中,我已经创建了带有#objectmissing table的catch块,为什么数据没有插入???@RakeshCS请仔细阅读我的答案,我不知道如何更好地解释它。数据没有插入到catch上的临时表中,因为完整的动态SQL甚至在开始执行之前就被拒绝,并且您的catch在动态SQL中。您好,Ezlo,我是SQL新手,所以我想知道在应该执行错误ocurs else select语句时,如何将错误数据插入catch。U在上面的查询中解释了如何逃逸错误,它将停止执行。如果我不知道哪个数据库有错误,哪个数据库执行了错误,那么逃逸错误就没有用了。。希望你明白我的意思