Скопируйте данные таблицы из хранимой процедуры - PullRequest
2 голосов
/ 23 апреля 2010

Я учусь использовать SQL и хранимые процедуры.Я знаю, что синтаксис неправильный:

Копирование данных из одной таблицы в другую таблицу в другой базе данных с помощью хранимой процедуры.Проблема в том, что я не знаю, в какую таблицу или в какую базу данных копировать.Я хочу использовать параметры и не указывать столбцы специально.

У меня есть 2 базы данных (Master_db и Master_copy) и одинаковая структура таблиц в каждой БД.

Я хочу быстро выбрать таблицув Master_db и скопируйте данные этой таблицы в таблицу Master_copy с тем же именем.Я придумал что-то вроде этого:

USE Master_DB
CREATE PROCEDURE TransferData
DEFINE @tableFrom, @tableTo, @databaseTo;

INSERT INTO @databaseTo.dbo.@databaseTo
SELECT * FROM Master_DB.dbo.@tableFrom
GO;

Самое близкое, что я мог получить, было это.Теперь проблема в том, что у меня есть столбец Timestamp, и он выдал ошибку:

"Невозможно вставить явное значение в столбец timestamp. Используйте INSERT со списком столбцов, чтобы исключить столбец timestamp, или вставьте DEFAULT встолбец метки времени. "

USE Kenneth_Integration
GO
CREATE PROCEDURE TransferData
  @table  SYSNAME
  ,@databaseTo SYSNAME
AS
DECLARE @sql NVARCHAR(MAX)

SET @sql = 'DELETE FROM ' + @databaseTo + '..' + @table + ' set identity_insert ' + @databaseTo + '.dbo.' + @table + 
    ' on INSERT INTO ' + @databaseTo + '.dbo.' + @table + ' SELECT * FROM Kenneth_Integration.dbo.' + @table

EXEC sp_executesql @sql
GO

Как обойти эту ошибку с этим SP?

Ответы [ 4 ]

3 голосов
/ 23 апреля 2010

Имена объектов в запросах SQL не могут быть параметризованы так, как вы пытаетесь.

Чтобы это работало, вам нужно использовать динамический SQL:

USE Master_DB
CREATE PROCEDURE TransferData
 @tableFrom   SYSNAME
 ,@tableTo    SYSNAME
 ,@databaseTo SYSNAME
AS
DECLARE @sql NVARCHAR(MAX)
SET @sql = 'INSERT INTO ' + @databaseTo+ '.dbo.' + @tableTo + '
            SELECT * FROM Master_DB.dbo.' + @tableFrom

EXEC sp_executesql @sql
GO;
1 голос
/ 23 апреля 2010

Я бы согласился с @EdHarper, что построение строки и последующее выполнение sp_executesql, вероятно, ваш лучший ответ.

Две вещи, которые следует иметь в виду, которые я не вижу в предыдущих ответах:

1) Возможно, вы уже скопировали данные в таблицы базы данных Master_copy ранее, поэтому вам, вероятно, необходимо удалить данные в целевой таблице перед началом операции копирования.

2) Если у вас есть удостоверение личностистолбцы в таблицах Master_copy (потому что вы использовали один и тот же сценарий Sql для генерации таблиц Master_db и Master_copy, например), тогда вам необходимо убедиться, что вы можете перезаписывать значения идентификаторов (это можно сделать с помощью set identity_insert в команда).

Таким образом, в качестве альтернативы (нет никакого смысла в повторном ответе) и, как вы знаете, имена баз данных, вы можете просто денормализовать этот подход и написать простую хранимую процедуру для каждой таблицы.

Допустим, у вас есть таблица с именем «персона», которую вы можете написать:

create procedure TransferDataPerson 
as

delete from Master_copy..Person

set identity_insert Master_copy..Person on

insert into Master_copy..Person
select * from Master_db..Person

... и так далее для каждой таблицы.

1 голос
/ 23 апреля 2010

Только динамический SQL допускает использование переменных в качестве имен таблиц.Например:

create procedure dbo.TransferData(
    @src varchar(50),
    @dest varchar(50))
as
declare @query varchar(500)
set @query = 'INSERT INTO ' + @src +
    'SELECT * FROM ' + @dest
exec @query
go
1 голос
/ 23 апреля 2010

Я предлагаю написать функцию, которая возвращает таблицу чем использовать оператор вставки select

Разница между процедурой и функцией, чем вы не можете написать select procedure но ты можешь написать выберите функцию

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...