2

長いスクリプトがあり、必要なときにファイル全体を実行でき、その一部が既に実行されているかどうかを心配する必要がありません。しかし、以下のスクリプトは私に問題を与えています。何らかの理由で、列 'EntityID' および 'EntityType' が存在しない場合でも IF ステートメントを通過しています。この場合、IF ステートメントを通過すべきではありません。誰かが何が悪いのか教えてもらえますか?

IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'Notes' AND COLUMN_NAME IN ('EntityId', 'EntityType'))
BEGIN
    BEGIN TRANSACTION
        --Delete notes where EntityType and EntityID are both NULL
        DELETE FROM [dbo].[Notes]
        WHERE [EntityId] = NULL 
        AND [EntityType] = NULL
        --Delete notes where the corresponding contact or account has been deleted.
        OR [ID] IN (9788, 10684, 10393, 10718, 10719)

        --Populate new columns with all existing data
        UPDATE [dbo].[Notes]
        SET [AccountId] = [EntityId]
        WHERE [EntityType] = 1

        UPDATE [dbo].[Notes]
        SET [ContactId] = [EntityId]
        WHERE [EntityType] = 2

        --Delete EntityId and EntityType columns from the Notes table
        ALTER TABLE [dbo].[Notes]
        DROP COLUMN [EntityId], [EntityType]
    COMMIT
END
GO

テーブルのスクリプト

CREATE TABLE [dbo].[Notes](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [AnnotationID] [uniqueidentifier] NULL,
    [CreatedBy] [int] NULL,
    [CreatedDate] [datetime] NULL,
    [NoteText] [ntext] NULL,
    [OriginalAnnotationID] [uniqueidentifier] NULL,
    [Active] [bit] NULL,
    [ContactId] [int] NULL,
    [AccountId] [int] NULL,
 CONSTRAINT [PK_Notes] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

GO

ALTER TABLE [dbo].[Notes]  WITH CHECK ADD  CONSTRAINT [FK_Account_ID] FOREIGN KEY([AccountId])
REFERENCES [dbo].[Account] ([ID])
GO

ALTER TABLE [dbo].[Notes] CHECK CONSTRAINT [FK_Account_ID]
GO

ALTER TABLE [dbo].[Notes]  WITH CHECK ADD  CONSTRAINT [FK_ContactId_ID] FOREIGN KEY([ContactId])
REFERENCES [dbo].[Contact] ([ID])
GO

ALTER TABLE [dbo].[Notes] CHECK CONSTRAINT [FK_ContactId_ID]
GO

エラー:

Msg 207, Level 16, State 1, Line 6
Invalid column name 'EntityId'.
Msg 207, Level 16, State 1, Line 7
Invalid column name 'EntityType'.
Msg 207, Level 16, State 1, Line 12
Invalid column name 'EntityType'.
Msg 207, Level 16, State 1, Line 16
Invalid column name 'EntityType'.
4

2 に答える 2

4

マーティンは間違いなく何かに夢中でした。内部のものIFは、解析時にパーサーによって処理されており、IFパンアウトするかどうかは無視されます。これは、あなたができないのと同じ理由です:

IF 1 = 1
  CREATE TABLE #x(a INT);
ELSE
  CREATE TABLE #x(b INT);

1 つの回避策は、動的 SQL を使用することです。

IF EXISTS ...
BEGIN
  BEGIN TRANSACTION;

  DECLARE @sql NVARCHAR(MAX);

  SET @sql = N'
        DELETE FROM [dbo].[Notes]
        WHERE [EntityId] IS NULL 
        AND [EntityType] IS NULL
        --Delete notes where the corresponding contact or account has been deleted.
        OR [ID] IN (9788, 10684, 10393, 10718, 10719)

        --Populate new columns with all existing data
        UPDATE [dbo].[Notes]
        SET [AccountId] = [EntityId]
        WHERE [EntityType] = 1

        UPDATE [dbo].[Notes]
        SET [ContactId] = [EntityId]
        WHERE [EntityType] = 2

        --Delete EntityId and EntityType columns from the Notes table
        ALTER TABLE [dbo].[Notes]
        DROP COLUMN [EntityId], [EntityType]';

    EXEC sp_executesql @sql;

    COMMIT TRANSACTION;
END

ただし、両方の列が存在することを確認する必要があります。

于 2012-06-22T18:46:18.583 に答える
0

問題は、列の 1 つが存在し、両方が存在しないことだと思われます。次のことを試してください。

IF 2 = (SELECT count(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'Notes' AND COLUMN_NAME IN ('EntityId', 'EntityType')) 
于 2012-06-22T18:00:45.827 に答える