【问题标题】:sql server stored procedure check if exists table in other database and rename itsql server存储过程检查其他数据库中是否存在表并重命名
【发布时间】:2026-01-05 09:45:01
【问题描述】:

有 2 个数据库:MAIN 和 IP2LOCATION

在 MAIN 中,我有以下存储过程:

CREATE PROCEDURE dbo.Update_IP2Location_DB11_from_CSV
AS
BEGIN
    IF  NOT EXISTS (SELECT * FROM sys.objects 
    WHERE object_id = OBJECT_ID(N'[ip2location].[dbo].[db11_new]') AND type in (N'U'))
        BEGIN
            CREATE TABLE [ip2location].[dbo].[db11_new]
            (
                [ip_from]       bigint          NOT NULL,
                [ip_to]         bigint          NOT NULL,
                [country_code]  nvarchar(2)     NOT NULL,
                [country_name]  nvarchar(64)    NOT NULL,
                [region_name]   nvarchar(128)   NOT NULL,
                [city_name]     nvarchar(128)   NOT NULL,
                [latitude]      float           NOT NULL,
                [longitude]     float           NOT NULL,
                [zip_code]      nvarchar(30)    NOT NULL,
                [time_zone]     nvarchar(8)     NOT NULL,
            ) ON [PRIMARY]

            CREATE INDEX [ip_from] ON [ip2location].[dbo].[db11_new]([ip_from])
        END
    ELSE
        BEGIN
            DELETE FROM [ip2location].[dbo].[db11_new]
        END

    BULK INSERT [ip2location].[dbo].[db11_new]
        FROM 'D:\IP2LOCATION-LITE-DB11.CSV'
        WITH
        ( FORMATFILE = 'C:\inetpub\wwwroot\ws\DB11_ip4.FMT')

    EXEC sp_rename N'dbo.db11', N'db11_old', 'OBJECT'
    EXEC sp_rename N'ip2location.dbo.db11_new', N'db11', 'OBJECT'   
END

不能正常工作:

如果 db11_new 不存在,它(正确地)创建它,但如果它存在.. 我明白了

数据库中已经有一个名为“db11_new”的对象。

所以好像有什么问题

IF  NOT EXISTS (SELECT * FROM sys.objects 
WHERE object_id = OBJECT_ID(N'[ip2location].[dbo].[db11_new]') AND type in (N'U'))

并且在使用 2 Rename 的过程结束时,我(总是)得到以下答案

消息 15248,级别 11,状态 1,过程 sp_rename,第 359 行 要么参数@objname 不明确,要么声明的@objtype (OBJECT) 错误。

似乎问题是因为存储过程没有存储到 ip2location DB 中,而是存储在另一个数据库中..

可以提出一个解决方案,考虑到我更愿意将所有存储过程保留在 MAIN DB 中,因为所有其他存储空间都存在?

谢谢

【问题讨论】:

  • db11_old 发生了什么?第一次运行此过程后,它会创建表 db11_old,当第二次尝试运行此 SP 时,它会出现 sb11_oldalready 出现的错误。

标签: sql-server stored-procedures table-rename


【解决方案1】:
therefore it seems there is something wrong in
IF  NOT EXISTS (SELECT * FROM sys.objects 
WHERE object_id = OBJECT_ID(N'[ip2location].[dbo].[db11_new]') AND type in (N'U'))

您的分析是正确的。 sys.objects 目录视图将返回当前数据库上下文中的对象 (MAIN)。虽然您可以只使用 3 部分名称 (ip2location.sys.objects),但我建议您只需检查 NULL OBJECT_ID 函数结果:

IF  OBJECT_ID(N'[ip2location].[dbo].[db11_new]', 'U') IS NULL
        BEGIN
            CREATE TABLE [ip2location].[dbo].[db11_new]
            (
                [ip_from]       bigint          NOT NULL,
                [ip_to]         bigint          NOT NULL,
                [country_code]  nvarchar(2)     NOT NULL,
                [country_name]  nvarchar(64)    NOT NULL,
                [region_name]   nvarchar(128)   NOT NULL,
                [city_name]     nvarchar(128)   NOT NULL,
                [latitude]      float           NOT NULL,
                [longitude]     float           NOT NULL,
                [zip_code]      nvarchar(30)    NOT NULL,
                [time_zone]     nvarchar(8)     NOT NULL,
            ) ON [PRIMARY];

            CREATE INDEX [ip_from] ON [ip2location].[dbo].[db11_new]([ip_from]);
        END;
    ELSE
        BEGIN
            DELETE FROM [ip2location].[dbo].[db11_new];
        END;

【讨论】:

  • 嗯...OBJECT_ID(N'[ip2location].[dbo].[db11_new]', 'U') IS NULL 似乎有效,而ip2location.sys.object....... 无效.. 无论如何.. 没关系:如何解决 sp_rename 问题?谢谢
  • 找到:EXEC ip2location.dbo.sp_rename N'dbo.db11', N'db11_old'
【解决方案2】:

sys.objects 和 sp_rename 是本地对象。 尝试使用这个:

IF  NOT EXISTS (SELECT * FROM ip2location.sys.objects 
    WHERE object_id = OBJECT_ID(N'[dbo].[db11_new]') AND type in (N'U'))

    EXEC ip2location.sp_rename N'dbo.db11_new', N'db11', 'OBJECT'   

也许有帮助...

或者,当您想在另一个数据库中执行操作时,您可以在动态 sql 中编写代码,然后直接在另一个数据库中执行。

https://msdn.microsoft.com/en-us/library/ms188001.aspx

【讨论】:

  • 嗨!感谢您的回答,但我已经尝试添加“ip2location”。在某些地方,也如您所建议的那样,但它不适用于两种情况:-(
【解决方案3】:

我已经测试了这个查询(没有上传 csv)

一开始我删除了对ip2location的所有引用:

CREATE PROCEDURE dbo.Update_IP2Location_DB11_from_CSV
AS
BEGIN
IF  NOT EXISTS (SELECT * FROM sys.objects 
    WHERE object_id = OBJECT_ID(N'dbo.db11_new') AND type in (N'U'))
        BEGIN
            CREATE TABLE [dbo].[db11_new]
            (
                [ip_from]       bigint          NOT NULL,
                [ip_to]         bigint          NOT NULL,
                [country_code]  nvarchar(2)     NOT NULL,
                [country_name]  nvarchar(64)    NOT NULL,
                [region_name]   nvarchar(128)   NOT NULL,
                [city_name]     nvarchar(128)   NOT NULL,
                [latitude]      float           NOT NULL,
                [longitude]     float           NOT NULL,
                [zip_code]      nvarchar(30)    NOT NULL,
                [time_zone]     nvarchar(8)     NOT NULL,
            ) ON [PRIMARY]

            CREATE INDEX [ip_from] ON [dbo].[db11_new]([ip_from])
        END
    ELSE
        BEGIN
            DELETE FROM [dbo].[db11_new]
        END

    BULK INSERT [dbo].[db11_new]
        FROM 'D:\IP2LOCATION-LITE-DB11.CSV'
        WITH
        ( FORMATFILE = 'C:\inetpub\wwwroot\ws\DB11_ip4.FMT')

    EXEC sp_rename N'dbo.db11', N'db11_old', 'OBJECT'
    EXEC sp_rename N'dbo.db11_new', N'db11', 'OBJECT'   
END
GO

首次运行:

我没有db11* 表。执行带给我:

消息 15248,级别 11,状态 1,过程 sp_rename,第 401 行 [批处理 开始行 2] 参数 @objname 不明确或 声称@objtype (OBJECT) 是错误的。注意:更改任何部分 对象名称可能会破坏脚本和存储过程。

这意味着 db11_new 已创建,然后在 db11 中重命名,但未找到 db11_old,因此出现此错误。我的数据库中有db11 表。

第二次运行:

警告:更改对象名称的任何部分都可能会破坏脚本和 存储过程。警告:更改对象名称的任何部分都可能 中断脚本和存储过程。

这意味着所有内容都已创建并重命名。

第三轮:

消息 15335,级别 11,状态 1,过程 sp_rename,第 509 行 [批处理 开始行 2] 错误:新名称“db11_old”已用作 OBJECT 名称,并且会导致不允许的重复。消息 15335,级别 11,状态 1,过程 sp_rename,第 509 行 [批处理开始 第 2 行] 错误:新名称“db11”已用作对象名称 并且会导致不允许的重复。

所以每次下一次重新运行你都会得到同样的错误。

我的建议是对db11_old 做点什么。

【讨论】:

  • 嗨!感谢您的回答,我的分析差异不大:无论如何,由于 sys.object 和 sp_rename 是本地对象,因此需要在这两个语句之前添加一个 ip2.location.dbo 。如果对某人有用,我会尽快发布完整的解决方案
【解决方案4】:

感谢 Reboon 和 Dan Guzman 提供的解决方案,改进不大:

CREATE PROCEDURE dbo.spA_Update_IP2Location_DB11_from_CSV
AS
BEGIN

IF  OBJECT_ID(N'[ip2location].[dbo].[db11_new]', 'U') IS NULL
    BEGIN

        CREATE TABLE [ip2location].[dbo].[db11_new](
            [ip_from] bigint NOT NULL,
            [ip_to] bigint NOT NULL,
            [country_code] nvarchar(2) NOT NULL,
            [country_name] nvarchar(64) NOT NULL,
            [region_name] nvarchar(128) NOT NULL,
            [city_name] nvarchar(128) NOT NULL,
            [latitude] float NOT NULL,
            [longitude] float NOT NULL,
            [zip_code] nvarchar(30) NOT NULL,
            [time_zone] nvarchar(8) NOT NULL,
        ) ON [PRIMARY]

        CREATE INDEX [ip_from] ON [ip2location].[dbo].[db11_new]([ip_from]) ON [PRIMARY]

    END
ELSE
    BEGIN
        delete from [ip2location].[dbo].[db11_new]
    END

BULK INSERT [ip2location].[dbo].[db11_new]
    FROM 'D:\IP2LOCATION-LITE-DB11.CSV'
    WITH
    ( FORMATFILE = 'C:\inetpub\wwwroot\ws\DB11_ip4.FMT' )

BEGIN TRANSACTION
    EXEC ip2location.dbo.sp_rename N'dbo.db11', N'db11_old'
    EXEC ip2location.dbo.sp_rename N'dbo.db11_new', N'db11'
    IF  OBJECT_ID(N'[ip2location].[dbo].[db11_old]', 'U') IS NOT NULL
        BEGIN
            DROP  TABLE ip2location.dbo.db11_old
        END
COMMIT TRANSACTION  
END

【讨论】:

    最近更新 更多