1

有 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 数据库中,而是存储在另一个数据库中。

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

谢谢

4

4 回答 4

1

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

于 2016-05-19T11:35:15.450 回答
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;
于 2016-05-19T12:23:32.897 回答
0

我已经测试了这个查询(没有 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' 已用作 OBJECT 名称,并且会导致不允许的重复。

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

我的建议是对db11_old.

于 2016-05-19T13:54:46.433 回答
0

感谢 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
于 2016-05-19T15:35:23.797 回答