2016-02-29 59 views
2

我編寫了一個T-SQL腳本來更新生產中的現有數據庫。SQL Server - 當列不存在時TSQL失敗

基本上,如果存在一列,腳本必須創建一個新表,將現有數據插入到新表中,最後刪除該列。

  1. 檢查在(dbo.Patient) 1.1存在列創建一個新的表(dbo.PatientPhoto)從dbo.Patient.Photo 1.2遷移數據到dbo.PatientPhoto 1.3刪除列dbo.Patient。照片

  2. 如果列不存在,什麼也不做......

該腳本工作正常時,列存在,但是當列不存在失敗......它看起來像它在進入「一世F「子句事件(如果該列不存在)。

腳本:

-- Vérifier si la colonne Photo exists dans la table patient 
IF EXISTS(SELECT * FROM sys.columns 
      WHERE Name = N'Photo' AND Object_ID = Object_ID(N'Patient')) 
BEGIN 
    -- Vérifier si la table PatientPhoto existe et la créer si ce n'Est pas le cas 
    IF (NOT EXISTS (SELECT * 
       FROM INFORMATION_SCHEMA.TABLES 
       WHERE TABLE_SCHEMA = 'dbo' 
       AND TABLE_NAME = 'PatientPhoto')) 
     BEGIN 
      CREATE TABLE [dbo].[PatientPhoto](
       Id INT IDENTITY(1,1) NOT NULL, 
       PatientId UNIQUEIDENTIFIER NOT NULL, 
       [Photo] [varbinary](max) NOT NULL 
      ) 
     END 


    -- Vider la table PatientPhoto 
    DELETE FROM dbo.PatientPhoto 

    -- Populer la table PatientPhoto avec le contenu de la table patient 
    INSERT INTO PatientPhoto(PatientId, Photo) 
    SELECT Id, Photo FROM dbo.Patient 
    WHERE Photo IS NOT NULL 

    -- Supprimer la colonne Photo de la table patient 
    ALTER TABLE dbo.Patient DROP COLUMN Photo 
END 
+0

您是否嘗試過使用SQL Server Management Studio調試器來查找確切發生了什麼? – paul

+0

@paul是的,我做到了。它不會進入調試器。看起來它在執行之前解析腳本......當我手動解析查詢時,它成功完成... – Baral

+0

@Baral的問題是,爲什麼你甚至想要做這樣的事情醜陋。首先,我會說糟糕的建築。 SQL不是問題:-) – krtek

回答

3

正確,SQL Server必須能夠在您的整個查詢執行前驗證;即使它包含一個IF語句,可以防止它試圖訪問不存在的列。如果列不存在,它將不會讓該查詢執行,因爲它不驗證。

解決此問題的一種方法是對需要列可能不存在的腳本部分使用動態sql,因爲SQL Server在執行之前不會嘗試驗證動態sql。

+0

這就是我所害怕的......我討厭動態SQL:D謝謝@TabAlleman – Baral

+2

我不會將其描述爲驗證。它是*編譯*。它不能*編譯*批處理。 –