以下是我试图通过sqlcmd运行的一些Transact-SQL(SQL Server 2005)。
USE PUK;
GO
BEGIN TRANSACTION;
BEGIN TRY
-- - Modify RETRIEVAL_STAT
alter table dbo.RETRIEVAL_STAT add
SOURCE nvarchar(10) NULL,
ACCOUNTNUMBER nvarchar(50) NULL,
PUK nvarchar(20) NULL;
-- transform logic.
update dbo.RETRIEVAL_STAT set
SOURCE = 'XX',
ACCOUNTNUMBER = 'XX',
PUK = 'XX';
END TRY
BEGIN CATCH
SELECT
ERROR_NUMBER() AS ErrorNumber
,ERROR_SEVERITY() AS ErrorSeverity
,ERROR_STATE() AS ErrorState
,ERROR_PROCEDURE() AS ErrorProcedure
,ERROR_LINE() AS ErrorLine
,ERROR_MESSAGE() AS ErrorMessage;
IF @@TRANCOUNT > 0
ROLLBACK TRANSACTION;
END CATCH;
IF @@TRANCOUNT > 0
COMMIT TRANSACTION;
GO
我收到以下错误:
(0 rows affected)
Changed database context to 'PUK'.
Msg 207, Level 16, State 1, Server localhost\SQLEXPRESS, Line 11
Invalid column name 'SOURCE'.
Msg 207, Level 16, State 1, Server localhost\SQLEXPRESS, Line 11
Invalid column name 'ACCOUNTNUMBER'.
Msg 207, Level 16, State 1, Server localhost\SQLEXPRESS, Line 11
Invalid column name 'PUK'.
我猜这是因为alter语句引入的新列尚未提交,因此更新失败。
我的问题是如何才能让它工作呢?我希望这个作为单个事务运行,如果出现问题我可以回滚。这很重要,因为我还有更多的alter语句包括在内,而且我有点沮丧,我无法超越这一点。
非常感谢任何帮助!
罗布 :)
答案 0 :(得分:5)
即使我正在编写自己的答案 - 所有的归功于@Mikael Eriksson,他建议我需要将不同的批次与GO分开 - 以便改变表格的代码不会与使用更改的代码冲突表。谢谢Mikael!
USE PUK;
GO
BEGIN TRANSACTION;
BEGIN TRY
-- - Modify RETRIEVAL_STAT
alter table dbo.RETRIEVAL_STAT add
SOURCE nvarchar(10) NULL,
ACCOUNTNUMBER nvarchar(50) NULL,
PUK nvarchar(20) NULL;
END TRY
BEGIN CATCH
SELECT
ERROR_NUMBER() AS ErrorNumber
,ERROR_SEVERITY() AS ErrorSeverity
,ERROR_STATE() AS ErrorState
,ERROR_PROCEDURE() AS ErrorProcedure
,ERROR_LINE() AS ErrorLine
,ERROR_MESSAGE() AS ErrorMessage;
IF @@TRANCOUNT > 0
ROLLBACK TRANSACTION;
END CATCH;
IF @@TRANCOUNT > 0
COMMIT TRANSACTION;
GO
USE PUK;
GO
BEGIN TRANSACTION;
BEGIN TRY
-- transform logic.
UPDATE dbo.RETRIEVAL_STAT
SET SOURCE = 'ABC',
ACCOUNTNUMBER = ABC.ACCOUNTNUMBER,
PUK = ABC.PUK
FROM RETRIEVAL_STAT RS
INNER JOIN ABC
ON RS.SERVICE_NUMBER = ABC.SERVICENUMBER;
UPDATE dbo.RETRIEVAL_STAT
SET SOURCE = 'DEF',
ACCOUNTNUMBER = DEF.BILLINGACCOUNTNUMBER ,
PUK = DEF.PUK
FROM RETRIEVAL_STAT RS
INNER JOIN DEF
ON RS.SERVICE_NUMBER = DEF.SERVICENUMBER;
UPDATE dbo.RETRIEVAL_STAT
SET SOURCE = 'No Match'
WHERE SOURCE IS NULL;
-- Fix other columns that should be not nullable.
alter table dbo.RETRIEVAL_STAT
alter column SERVICE_NUMBER nvarchar (50) NOT NULL;
alter table dbo.DEF
alter column PUK nvarchar (20) NOT NULL;
END TRY
BEGIN CATCH
SELECT
ERROR_NUMBER() AS ErrorNumber
,ERROR_SEVERITY() AS ErrorSeverity
,ERROR_STATE() AS ErrorState
,ERROR_PROCEDURE() AS ErrorProcedure
,ERROR_LINE() AS ErrorLine
,ERROR_MESSAGE() AS ErrorMessage;
IF @@TRANCOUNT > 0
ROLLBACK TRANSACTION;
END CATCH;
IF @@TRANCOUNT > 0
COMMIT TRANSACTION;
GO
答案 1 :(得分:4)
SQL Server在编译代码时检查列。您可以使用动态SQL来解决该问题。
-- transform logic.
declare @SQL nvarchar(1000)
set @SQL =
'update dbo.RETRIEVAL_STAT set
SOURCE = @S,
ACCOUNTNUMBER = @A,
PUK = @P';
declare @Params nvarchar(1000);
set @Params = N'@S nvarchar(10), @A nvarchar(10), @P nvarchar(20)';
exec sp_executesql @SQL, @Params, N'S', N'A', N'P';