我编写了一个脚本,用于将数据从一个数据库复制到另一个具有(几乎)相同模式的数据库。
它在SSMS sqlcmd模式下运行良好,但是当我在sqlcmd
中尝试时它失败了。
如果它有任何区别,我在cli模式下从php脚本运行sqlcmd
。
我已经确认这两个参数都是有效的数据库名称。
BEGIN TRANSACTION copy_data_into_existing_database;
SET XACT_ABORT ON;
DECLARE @tables TABLE (table_name VARCHAR (MAX));
DECLARE @SQL VARCHAR (MAX);
INSERT INTO @tables
SELECT table_name
FROM [$(source)].information_schema.tables
WHERE table_schema = 'dbo' AND table_type = 'BASE TABLE';
/*
Dynamically generate the query for each table in the list
The query template is
- truncate the table
- if the table has an identity SET IDENTITY_INSERT ON
- INSERT INTO the destination DB with a list of all of the columns
- SELECT FROM the source DB with a list of all of the columns
- if the table has an identity SET IDENTITY_INSERT OFF
*/
SET @SQL =
(SELECT
-- this line is the truncate statement
'TRUNCATE TABLE [$(dest)].dbo.' + table_name + ';' +
-- this case statement sets the identity insert if the table has an identity
CASE WHEN (EXISTS(SELECT t.object_id
FROM [$(dest)].sys.tables t
INNER JOIN [$(dest)].sys.identity_columns ic ON t.object_id = ic.object_id
WHERE t.name = table_name))
THEN 'SET IDENTITY_INSERT [$(dest)].dbo.' + table_name + ' ON;'
ELSE '' END +
-- this line is the insert statement, the substring-select gets a CSV of all non-computed columns for this table
'INSERT INTO [$(dest)].dbo.' + table_name + '(' + SUBSTRING((SELECT ',' + c.name
FROM [$(source)].sys.columns c
INNER JOIN [$(source)].sys.tables t
ON c.object_id = t.object_id
WHERE is_computed = 0
AND t.name = table_name
FOR XML PATH ('')), 2, 99999) + ') ' +
-- this line is the select statement, it repeats the same substring-select from the previous line
'SELECT ' + SUBSTRING((SELECT ',' + c.name
FROM [$(source)].sys.columns c
INNER JOIN [$(source)].sys.tables t ON c.object_id = t.object_id
WHERE is_computed = 0 AND t.name = table_name
FOR XML PATH ('')), 2, 99999) + ' ' +
'FROM [$(source)].dbo.' + table_name + ';' +
-- this case statement sets the identity insert off it the table has an identity
CASE WHEN (EXISTS(SELECT t.object_id
FROM [$(dest)].sys.tables t
INNER JOIN [$(dest)].sys.identity_columns ic ON t.object_id = ic.object_id
WHERE t.name = table_name))
THEN 'SET IDENTITY_INSERT [$(dest)].dbo.' + table_name + ' OFF;'
ELSE '' END
FROM @tables tl
FOR XML PATH (''));
SELECT (@SQL);
SET @SQL = 'SET NOEXEC ON;' + @SQL; --DEBUG
EXECUTE (@SQL);
COMMIT TRANSACTION copy_data_into_existing_database;
当我在sqlcmd中运行它时会出现一堆语法错误。
Msg 102,Level 15,State 1,Server INTERNAL \ INTERNAL,Line 24
'。。。dbo'附近的语法不正确。消息102,级别15,状态1,服务器内部\内部,第29行
')'附近的语法不正确。消息156,级别15,状态1,服务器内部\内部,第39行
关键字“FOR”附近的语法不正确。消息156,级别15,状态1,服务器内部\内部,第45行
关键字“FOR”附近的语法不正确。Msg 102,Level 15,State 1,Server INTERNAL \ INTERNAL,Line 51
')'附近的语法不正确。
答案 0 :(得分:1)
问题在于字符串是双引号。我在命令行输入了这个:
sqlcmd -Sinternal\internal -iV:\inventory2-temp-rollout\MigrationHelpers\CopyDataIntoExistingDb.sql -v source="'products_live'" -v dest="'products'"
我删除了单引号:
sqlcmd -Sinternal\internal -iV:\inventory2-temp-rollout\MigrationHelpers\CopyDataIntoExistingDb.sql -v source="products_live" -v dest="products"