数据脚本生成的问题

时间:2012-05-30 21:42:31

标签: sql-server ssms

我很少使用SQL Server,在专业环境中我一直很清楚!我正在做一个宠物项目,但是我在编写脚本方面遇到了问题。

我有一个在线数据库,我需要从中提取所有内容。我使用任务>在SQL Server Management Studio中生成脚本选项。以下是脚本创建的一个insert语句的示例(我有1,000个这样的插入):

INSERT [dbo].[NewComics] ([NewComicId], [Title], [Subtitle], [ReleaseDate], [CollectionId]) VALUES (366, N'Hawk & Dove 1:                                                                                      ', N'First Strikes                                                                                       ', CAST(0x00009F6F00000000 AS DateTime), 248)

我有两个问题:

(a)我想从两个title元素中删除所有空格 (b)我不想要十六进制日期 - 我想要像2006-09-01(yyyy-mm-dd)这样可读的东西

INSERT [dbo].[NewComics] ([NewComicId], [Title], [Subtitle], [ReleaseDate], [CollectionId]) VALUES (366, N'Hawk & Dove 1:', N'First Strikes', '2006-09-01', 248)

将约3,000个插入语句更改为此修订格式的最快方法是什么?

仅供参考 - 这是表格的设计:

[NewComicId] [int] NOT NULL,
[Title] [nchar](100) NOT NULL,
[Subtitle] [nchar](100) NULL,
[ReleaseDate] [datetime] NOT NULL,
[CollectionId] [int] NOT NULL,

提前致谢!

2 个答案:

答案 0 :(得分:5)

是的,生成脚本遗憾地将datetime列编写为CONVERT(binary_value,Datetime)。我会尝试回答为什么(或者更重要的是,如果有办法改变行为)。我怀疑原因是为了避免在具有不同语言环境/区域设置等的不同机器上运行脚本时出现任何问题。我不知道是否有办法在此期间改变这种情况,但是Management Studio不是只有这样才能编写数据脚本...你可以查看第三方产品,如Red-Gate的SQL数据比较。

如果它真的只有3,000行,并且您打算在不同的服务器上运行生成的脚本,请停止使用向导并执行此操作(乍一看这看起来很可怕,但它会执行您想要的几项操作 - 输出一个准备好复制,粘贴和运行的脚本,具有格式良好和可读的日期,插入多行VALUES 1000,其间插入GO命令,甚至处理标题,副标题和集合中可能为NULL的值:

DECLARE @newtable SYSNAME = 'dbo.NewComics';

SET NOCOUNT ON;

;WITH x AS (SELECT TOP (4000) s = '(' 
    + CONVERT(VARCHAR(12), NewComicId) + ','
    + COALESCE('N''' + REPLACE(RTRIM(Title), '''', '''''') + '''', 'NULL') + ',' 
    + COALESCE('N''' + REPLACE(RTRIM(SubTitle), '''', '''''') + '''', 'NULL') 
    + ', ''' + CONVERT(CHAR(8), ReleaseDate, 112) + ' '
    + CONVERT(CHAR(8), ReleaseDate, 108) + ''','
    + CONVERT(VARCHAR(12), COALESCE(CollectionId, 'NULL')) + ')',
  rn = ROW_NUMBER() OVER (ORDER BY NewComicId)
  FROM dbo.OldComics ORDER BY NewComicId
),
y AS
(
SELECT [/*a*/] = 1, [/*b*/] = 'SET NOCOUNT ON;
GO
INSERT ' + @newtable + ' VALUES'
UNION ALL 
SELECT 2, s = CASE WHEN rn > 1 THEN ',' ELSE '' END + s
 FROM x WHERE rn BETWEEN 1 AND 1000
UNION ALL 
SELECT 3, 'GO' UNION ALL 
SELECT 4, s = CASE WHEN rn > 1001 THEN ',' ELSE '' END + s
 FROM x WHERE rn BETWEEN 1001 AND 2000
UNION ALL 
SELECT 5, 'GO' UNION ALL 
SELECT 6, s = CASE WHEN rn > 2001 THEN ',' ELSE '' END + s
 FROM x WHERE rn BETWEEN 2001 AND 3000
UNION ALL 
SELECT 7, 'GO' UNION ALL 
SELECT 8, s = CASE WHEN rn > 3001 THEN ',' ELSE '' END + s
 FROM x WHERE rn BETWEEN 3001 AND 4000
)
SELECT [/*b*/] FROM y ORDER BY [/*a*/];

(如果您有3000或3001行,则可能必须使用它,如果超过4000,则可能需要添加另外几个联合。)

如果要将数据移动到同一实例上的其他表或不同数据库,请使用@swasheck提供的脚本(并再次停止使用向导)。

您可能已经注意到这里的一个共同趋势:如果您不喜欢它为日期输出的二进制格式,请停止使用生成脚本向导。

答案 1 :(得分:2)

所以,如果这是我,那么我要做的就是在一个单独的数据库中构建表结构:

CREATE TABLE NewComics (
[NewComicId] [int] identity (0,1) NOT NULL,
[Title] [nvarchar](100) NOT NULL,
[Subtitle] [nvarchar](100) NULL,
[ReleaseDate] [datetime] NOT NULL,
[CollectionId] [int] NOT NULL
);

ALTER TABLE [NewComics]
ADD CONSTRAINT PK_NewComicsID PRIMARY KEY;

然后使用SQL来清理数据,如下所示:

INSERT INTO [NewDatabase].[dbo].[NewComics] (Title, Subtitle, ReleaseDate, CollectionID) 
SELECT 
    LTRIM(RTRIM(Title))
    , LTRIM(RTRIM(Subtitle))
    , CAST(ReleaseDate as Datetime)
    , CollectionID 
FROM [OldDatabase].[dbo].[NewComics];

或者,您可以使用相同的SELECT查询:

SELECT 
    NewComicID
    , LTRIM(RTRIM(Title))
    , LTRIM(RTRIM(Subtitle))
    , CAST(ReleaseDate as Datetime)
    , CollectionID 
FROM [OldDatabase].[dbo].[NewComics];

作为导入/导出数据任务的源(在您用于Generate Scripts的同一菜单中)。此服务器上的[OldDatabase]将是源,此服务器上的[NewDatabase]将是目标。确保选中所有标识插入的框。