Sql server 单个T-SQL语句单独运行良好,但在组合时运行不好
我有一堆SQL语句,我想执行它们来更新数据库的模式-它们都可以单独运行(即,当我一个接一个地手动运行它们时),但是当我试图将它们组合到一个脚本中,并围绕一些版本控制逻辑时,我遇到了问题 我的脚本如下:Sql server 单个T-SQL语句单独运行良好,但在组合时运行不好,sql-server,tsql,Sql Server,Tsql,我有一堆SQL语句,我想执行它们来更新数据库的模式-它们都可以单独运行(即,当我一个接一个地手动运行它们时),但是当我试图将它们组合到一个脚本中,并围绕一些版本控制逻辑时,我遇到了问题 我的脚本如下: DECLARE @VersionCode varchar(20) DECLARE @Description varchar(50) DECLARE @Author varchar(20) DECLARE @AppVersion varchar (10) SET @VersionCode = 'v
DECLARE @VersionCode varchar(20)
DECLARE @Description varchar(50)
DECLARE @Author varchar(20)
DECLARE @AppVersion varchar (10)
SET @VersionCode = 'version code';
SET @Description = 'description';
SET @Author = 'author';
SET @AppVersion = 'app version';
BEGIN
IF NOT EXISTS (SELECT * FROM [Version] WHERE [VersionCode] = @VersionCode)
BEGIN
ALTER TABLE [Journal] ADD [BreakDurationNew] INT NULL
UPDATE [Journal] SET BreakDurationNew = BreakDuration
ALTER TABLE [Journal] DROP COLUMN [BreakDuration]
EXEC sp_rename 'Journal.BreakDurationNew', 'BreakDuration', 'COLUMN';
-- create triggers on JournalBreak so that BreakDuration on Journal is updated
CREATE TRIGGER TR_JournalBreak_Insert ON [JournalBreak]
FOR INSERT
AS
BEGIN
UPDATE [Journal] SET BreakDuration = (coalesce([dbo].[CalculateJournalBreak]([JournalId]),(0))) WHERE [JournalId] IN (SELECT JournalId FROM INSERTED)
END
CREATE TRIGGER TR_JournalBreak_Update ON [JournalBreak]
FOR UPDATE
AS
BEGIN
UPDATE [Journal] SET BreakDuration = (coalesce([dbo].[CalculateJournalBreak]([JournalId]),(0))) WHERE [JournalId] IN (SELECT JournalId FROM INSERTED)
UPDATE [Journal] SET BreakDuration = (coalesce([dbo].[CalculateJournalBreak]([JournalId]),(0))) WHERE [JournalId] IN (SELECT JournalId FROM DELETED)
END
-- insert version record
INSERT INTO [RG].[dbo].[Version] (VersionCode, Description, Author, AppVersion) VALUES
(@VersionCode, @Description, @Author, @AppVersion)
END
END
我的猜测是我的脚本在语法上有一些错误(或一大堆错误!),但我目前无法发现。有人能帮忙吗
干杯 试试看@GordonLinoff评论
DECLARE @VersionCode VARCHAR(20) = 'version code'
DECLARE @Description VARCHAR(50) = 'description'
DECLARE @Author VARCHAR(20) = 'author'
DECLARE @AppVersion VARCHAR(10) = 'app version'
DECLARE @CMD NVARCHAR(Max) = ''
BEGIN
IF NOT EXISTS (
SELECT *
FROM [Version]
WHERE [VersionCode] = @VersionCode
)
BEGIN
SET @CMD = 'ALTER TABLE [Journal] ADD [BreakDurationNew] INT NULL'
EXEC SP_EXECUTESQL @CMD
SET @CMD = 'UPDATE [Journal] SET BreakDurationNew = BreakDuration
ALTER TABLE [Journal] DROP COLUMN [BreakDuration]'
EXEC SP_EXECUTESQL @CMD
EXEC sp_rename 'Journal.BreakDurationNew','BreakDuration','COLUMN';
-- create triggers on JournalBreak so that BreakDuration on Journal is updated
SET @CMD = '
CREATE TRIGGER TR_JournalBreak_Insert ON [JournalBreak]
FOR INSERT
AS
BEGIN
UPDATE [Journal] SET BreakDuration = (coalesce([dbo].[CalculateJournalBreak]([JournalId]),(0))) WHERE [JournalId] IN (SELECT JournalId FROM INSERTED)
END'
EXEC SP_EXECUTESQL @CMD
SET @CMD = '
CREATE TRIGGER TR_JournalBreak_Update ON [JournalBreak]
FOR UPDATE
AS
BEGIN
UPDATE [Journal] SET BreakDuration = (coalesce([dbo].[CalculateJournalBreak]([JournalId]),(0))) WHERE [JournalId] IN (SELECT JournalId FROM INSERTED)
UPDATE [Journal] SET BreakDuration = (coalesce([dbo].[CalculateJournalBreak]([JournalId]),(0))) WHERE [JournalId] IN (SELECT JournalId FROM DELETED)
END
'
EXEC SP_EXECUTESQL @CMD
-- insert version record
INSERT INTO [RG].[dbo].[Version] (VersionCode, Description, Author, AppVersion) VALUES
(@VersionCode, @Description, @Author, @AppVersion)
END
END
尝试一下@GordonLinoff评论
DECLARE @VersionCode VARCHAR(20) = 'version code'
DECLARE @Description VARCHAR(50) = 'description'
DECLARE @Author VARCHAR(20) = 'author'
DECLARE @AppVersion VARCHAR(10) = 'app version'
DECLARE @CMD NVARCHAR(Max) = ''
BEGIN
IF NOT EXISTS (
SELECT *
FROM [Version]
WHERE [VersionCode] = @VersionCode
)
BEGIN
SET @CMD = 'ALTER TABLE [Journal] ADD [BreakDurationNew] INT NULL'
EXEC SP_EXECUTESQL @CMD
SET @CMD = 'UPDATE [Journal] SET BreakDurationNew = BreakDuration
ALTER TABLE [Journal] DROP COLUMN [BreakDuration]'
EXEC SP_EXECUTESQL @CMD
EXEC sp_rename 'Journal.BreakDurationNew','BreakDuration','COLUMN';
-- create triggers on JournalBreak so that BreakDuration on Journal is updated
SET @CMD = '
CREATE TRIGGER TR_JournalBreak_Insert ON [JournalBreak]
FOR INSERT
AS
BEGIN
UPDATE [Journal] SET BreakDuration = (coalesce([dbo].[CalculateJournalBreak]([JournalId]),(0))) WHERE [JournalId] IN (SELECT JournalId FROM INSERTED)
END'
EXEC SP_EXECUTESQL @CMD
SET @CMD = '
CREATE TRIGGER TR_JournalBreak_Update ON [JournalBreak]
FOR UPDATE
AS
BEGIN
UPDATE [Journal] SET BreakDuration = (coalesce([dbo].[CalculateJournalBreak]([JournalId]),(0))) WHERE [JournalId] IN (SELECT JournalId FROM INSERTED)
UPDATE [Journal] SET BreakDuration = (coalesce([dbo].[CalculateJournalBreak]([JournalId]),(0))) WHERE [JournalId] IN (SELECT JournalId FROM DELETED)
END
'
EXEC SP_EXECUTESQL @CMD
-- insert version record
INSERT INTO [RG].[dbo].[Version] (VersionCode, Description, Author, AppVersion) VALUES
(@VersionCode, @Description, @Author, @AppVersion)
END
END
看起来你正试图发明某种补丁机制。我建议制作单独的脚本:
因此,我的建议是开发一个流控制工具,为它提供一个功能来确定服务器上的版本,并提供另一个功能-将适当的补丁脚本发送到
sqlcmd.exe
。并可能检查是否有错误。这甚至可能是一个批处理文件(*.cmd)。看起来您正试图发明某种修补机制。我建议制作单独的脚本:
因此,我的建议是开发一个流控制工具,为它提供一个功能来确定服务器上的版本,并提供另一个功能-将适当的补丁脚本发送到
sqlcmd.exe
。并可能检查是否有错误。这甚至可能是一个批处理文件(*.cmd)。您对t-SQL还没有“感觉”<例如,代码>创建触发器,需要是批处理中的第一个命令(或前面有GO
)。因此,除非使用动态SQL,否则不能有条件地创建触发器。@GordonLinoff太正确了!在研究这个问题时,我确实看到了CREATE TRIGGER的东西——即使我删除了两个CREATE TRIGGER语句,它也会因一些无害的东西而失败……“它因一些无害的东西而失败…”如何失败?@TT。很抱歉反应太晚。我得到的错误是在UPDATE[Journal]SET BreakDurationNew=BreakDuration
行上的无效列名'BreakDurationNew'
,这几乎表明它完全忽略了它前面的行(在其中添加了新列),将其全部包装在单独的动态SQL语句中。您还没有对t-SQL的“感觉”<例如,代码>创建触发器,需要是批处理中的第一个命令(或前面有GO
)。因此,除非使用动态SQL,否则不能有条件地创建触发器。@GordonLinoff太正确了!在研究这个问题时,我确实看到了CREATE TRIGGER的东西——即使我删除了两个CREATE TRIGGER语句,它也会因一些无害的东西而失败……“它因一些无害的东西而失败…”如何失败?@TT。很抱歉反应太晚。我得到的错误是在UPDATE[Journal]SET BreakDurationNew=BreakDuration
行上的无效列名'BreakDurationNew'
,这几乎表明它完全忽略了它前面的行(在其中添加了新列),将其全部打包到单独的动态SQL语句中。感谢您的回答。然而,它对我仍然不起作用。我得到的错误是,更新[Journal]SET BreakDurationNew=BreakDuration
行上的无效列名'BreakDurationNew'
,这几乎表明它完全忽略了它前面的行(这会在中添加新列)-类似于我简单地删除CREATE TRIGGER
commandsThanks以获取答案时的情况。然而,它对我仍然不起作用。我得到的错误是更新[Journal]SET BreakDurationNew=BreakDuration
行上的无效列名'BreakDurationNew'
,这几乎表明它完全忽略了它前面的行(在中添加了新列)-类似于我只是删除创建触发器
命令时的错误