我很少使用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,
提前致谢!
答案 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]
将是目标。确保选中所有标识插入的框。