2016-05-19 3 views
1

Есть 2 базы данных: MAIN и IP2LocationSQL Server хранится проверка процедура, если существует таблица в другой базе данных и переименовать его

в 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 не существует, то он (правильно) создает его, но если он существует .. Я получаю

There is already an object named 'db11_new' in the database.

поэтому кажется, что есть что-то неправильное в

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

, а также в конце процедуры с 2 Rename я (всегда) следующий ответ

Msg 15248, Level 11, State 1, Procedure sp_rename, Line 359 Either the parameter @objname is ambiguous or the claimed @objtype (OBJECT) is wrong.

кажется проблемой является потому, что sproc не хранится в базе данных ip2location DB, а в другой базе данных.

может предложить решение, учитывая, что я предпочел бы сохранить все sprocs в MAIN DB, так как есть ли там все остальные?

Благодаря

+0

И что случилось с 'db11_old'? После первого запуска этой процедуры он создает таблицу 'db11_old' при попытке запустить этот SP второй раз, когда он падает с ошибкой, которую представляет' sb11_old' уже. – gofr1

ответ

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), я предлагаю вам просто проверить результат NULLOBJECT_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; 
+0

Hmm ... 'OBJECT_ID (N '[ip2location]. [dbo]. [db11_new]', 'U') IS NULL' Кажется, работает в то время как 'ip2location.sys.object .......' не .. в любом случае .. это нормально: Как исправить проблему sp_rename? спасибо – Joe

+0

Найдено: 'EXEC ip2location.dbo.sp_rename N'dbo .db11 ', N'db11_old'' – Joe

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

+0

Привет! спасибо за ответ, но я уже пытался добавить «ip2location». в некоторых местах, также, как вы предложили, но это не работает для обоих случаев :-( – Joe

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* столов.Исполнение приносит мне:

Msg 15248, Level 11, State 1, Procedure sp_rename, Line 401 [Batch Start Line 2] Either the parameter @objname is ambiguous or the claimed @objtype (OBJECT) is wrong. Caution: Changing any part of an object name could break scripts and stored procedures.

Это означает, что db11_new был создан, и чем переименовано в db11, но db11_old не была найдена, так что я получил эту ошибку. Я получаю таблицу db11 в моей БД.

Второй запуск:

Caution: Changing any part of an object name could break scripts and stored procedures. Caution: Changing any part of an object name could break scripts and stored procedures.

Это означает, что все было создано и переименован.

Третий запуск:

Msg 15335, Level 11, State 1, Procedure sp_rename, Line 509 [Batch Start Line 2] Error: The new name 'db11_old' is already in use as a OBJECT name and would cause a duplicate that is not permitted. Msg 15335, Level 11, State 1, Procedure sp_rename, Line 509 [Batch Start Line 2] Error: The new name 'db11' is already in use as a OBJECT name and would cause a duplicate that is not permitted.

Таким образом, каждый следующий повторно запустить вы получите это те же ошибки.

Мое предложение сделать что-то около db11_old.

+0

Привет! Спасибо за ответ, мой анализ немного отличается: во всяком случае, поскольку sys.object и sp_rename являются локальными объектами, необходимо добавить ip2.location.dbo перед обоими инструкциями. I опубликует полное решение как можно скорее, если оно может быть полезно для кого-то – Joe

0

Благодаря Reboon и Дэн Гузман здесь решение, немного улучшилось:

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 
Смежные вопросы