sql कोशिश करो... कैच काम करने के लिए नहीं लगता है




sql-server error-handling (3)

मुझे लगता है कि आप वास्तव में क्या हासिल करना चाहते हैं:

IF OBJECT_ID('tempdb..#LookupLinks') IS NOT NULL --Table already exists
BEGIN
    TRUNCATE TABLE #LookupLinks
    PRINT N'#LookupLinks already existed and was truncated.'; 
END
ELSE
BEGIN 
    CREATE TABLE #LookupLinks(
        [SyncID] uniqueidentifier,
        [Name] nvarchar(50),
        [SQLTable] nvarchar(50)
    )
END

मेरे पास निम्न कोड का कोड है जो यह सुनिश्चित करने के लिए है कि अस्थायी तालिका मौजूद नहीं है यदि टेबल मौजूद है तो मैं उसे छोटा करना चाहता हूं।

CREATE TABLE #LookupLinks(
        [SyncID] uniqueidentifier,
        [Name] nvarchar(50),
        [SQLTable] nvarchar(50)
    ) --I create this just to test my try-catch

BEGIN TRY
    CREATE TABLE #LookupLinks(
        [SyncID] uniqueidentifier,
        [Name] nvarchar(50),
        [SQLTable] nvarchar(50)
    )
END TRY
BEGIN CATCH
    PRINT N'#LookupLinks already existed and was truncated.';
    TRUNCATE TABLE #LookupLinks
END CATCH

मैं यह करना चाहता हूं:

  1. अस्थायी तालिका बनाई गई है
  2. इसे फिर से बनाने का प्रयास
  3. त्रुटि हमें पकड़ में भेजता है
  4. टेबल काट दिया गया है और सब कुछ सामान्य रूप से जारी है

क्या होता है:

त्रुटि: डेटाबेस में '#LookupLinks' का नाम पहले से मौजूद है

मुझसे यहां क्या गलत हो रहा है?


इसका कारण यह है कि SQL सर्वर पूर्ण बैच को पार्स करता है और मान्य करता है। इसलिए जब दूसरा CREATE TABLE विवरण पार्स करते हैं, तो यह कहने में त्रुटियां होती हैं:

डाटाबेस में पहले से ही '# लुकअप लिंक' नाम का ऑब्जेक्ट है।

यह उदाहरण देखें:

IF 1 = 1 BEGIN
    CREATE TABLE #temp(col INT)
END
ELSE BEGIN
    CREATE TABLE #temp(col INT)
END

यह कहकर एक त्रुटि उत्पन्न करता है:

डाटाबेस में '#temp' नाम से एक वस्तु पहले से मौजूद है

Dynamic SQL का इस्तेमाल करना है

-- CREATE the table for testing
IF OBJECT_ID('tempdb..#LookupLinks') IS NOT NULL 
    DROP TABLE #LookupLinks 
CREATE TABLE #LookupLinks(
        [SyncID] uniqueidentifier,
        [Name] nvarchar(50),
        [SQLTable] nvarchar(50)
    ) 


-- Final query
IF OBJECT_ID('tempdb..#LookupLinks') IS NOT NULL BEGIN
    TRUNCATE TABLE #LookupLinks
    PRINT N'#LookupLinks already existed and was truncated.'
END
ELSE BEGIN
    DECLARE @sql NVARCHAR(MAX) = ''
    SELECT @sql = '
        CREATE TABLE #LookupLinks(
            [SyncID] uniqueidentifier,
            [Name] nvarchar(50),
            [SQLTable] nvarchar(50)
        )'
    EXEC sp_executesql @sql
    PRINT N'#LookupLinks was created.'
END

यदि आपके पास पहले CREATE TABLE कथन नहीं है, तो आपकी क्वेरी बस ठीक काम करेगी। या अगर आप BEGIN TRY से पहले एक GO डालते हैं।

IF OBJECT_ID('tempdb..#LookupLinks') IS NOT NULL 
    DROP TABLE #LookupLinks -- DROP FIRST

CREATE TABLE #LookupLinks(
        [SyncID] uniqueidentifier,
        [Name] nvarchar(50),
        [SQLTable] nvarchar(50)
    ) --I create this just to test my try-catch
GO
BEGIN TRY
    CREATE TABLE #LookupLinks(
        [SyncID] uniqueidentifier,
        [Name] nvarchar(50),
        [SQLTable] nvarchar(50)
    )
END TRY
BEGIN CATCH
    PRINT N'#LookupLinks already existed and was truncated.';
    TRUNCATE TABLE #LookupLinks
END CATCH

फिर भी, ऐसा इसलिए है क्योंकि SQL सर्वर संपूर्ण बैच को सत्यापित करता है और मान्य करता है। GO वक्तव्य बयान अपने ही बैचों में रखेगा, इस प्रकार त्रुटि अब नहीं हो रही है।

यहां तक ​​कि CeOnSql का उत्तर ठीक काम करेगा।


TRY CATCH की TRY CATCH रन टाइम त्रुटि के लिए है आप क्या प्राप्त कर रहे हैं एक संकलन समय त्रुटि है अपने बयान से पहले PRINT 1 जोड़ें और आप देखेंगे कि कुछ भी निष्पादित नहीं हो रहा है

print 1

    CREATE TABLE #LookupLinks(
        [SyncID] uniqueidentifier,
        [Name] nvarchar(50),
        [SQLTable] nvarchar(50)
    );
BEGIN TRY

    CREATE TABLE #LookupLinks(
        [SyncID] uniqueidentifier,
        [Name] nvarchar(50),
        [SQLTable] nvarchar(50)
    );
END TRY
BEGIN CATCH
    PRINT N'#LookupLinks already existed and was truncated.';
    TRUNCATE TABLE #LookupLinks
END CATCH




try-catch