将SQL Server表数据从列结构转换为不同的列结构

时间:2017-06-02 11:42:04

标签: sql sql-server sql-server-2012

我刚接管了我的工作开发工作,基本上已经被SQL服务器深深抛入,我对查询和格式知之甚少,所以请放轻松我。

我正在使用Microsoft SQL Server 2012,基本上我想要实现的是从一个数据库表中获取数据,将其重新格式化为不同的结构,然后将其导入新数据库。我从创建软件的开发人员那里获得了以下代码。我对它正在做什么有一个基本的了解,但是我得到了一些错误,我似乎无法跟踪,无论我修复了什么,需要一些帮助确保格式正确,因为开发人员需要很长时间才能回答任何电子邮件问题

--Specify the database, table and columns we want to insert into
INSERT INTO new_database.dbo.QuizQuestions (uuid, [type], question, answer, created_date, modified_date,
master_category, master_decade, master_difficulty, is_editable, is_deletable, media)

--Get the data from the old database (old_database) and map the media filename to the media2 table in the new database

select 
   questions.uuid, 
   questions.newtype, 
   questions.QuestionText, 
   questions.AnswerText, 
   questions.CreatedDate, 
   questions.ModifiedDate, 
   questions.master_category, 
   questions.master_decade, 
   questions.master_difficulty,
   questions.IsEditable, 
   questions.IsDeletable,
   media.id as mediaid 
from
(
   select NEWID() as uuid, 
   CASE 
          WHEN qqt.TypeName = 'Sound' THEN 'Audio'
          ELSE qqt.TypeName
   END AS newtype,
   qq.QuestionText, qq.AnswerText, 
   qq.CreatedDate, 
   CASE 
          WHEN qq.ModifiedDate is NOT NULL THEN qq.ModifiedDate
          ELSE GETDATE()
   END as ModifiedDate, 
   CASE
          WHEN cat.id is NOT NULL THEN cat.id
          ELSE 1
   END as master_category,
   qqdc.QuizQuestionDecadeID as master_decade,
   qd.id as master_difficulty,
   qq.IsEditable, qq.IsDeletable,
   qq.FilePath,
   SUBSTRING(
          qq.FilePath, 
          len(qq.FilePath) - charindex('/', reverse(qq.FilePath)) + 2, 
          (len(qq.FilePath) - charindex('.', reverse(qq.FilePath))) - (len(qq.FilePath) - charindex('/', reverse(qq.FilePath))) - 1) as fname
   --len(qq.FilePath) - charindex('.', reverse(qq.FilePath)) as positionoflastdot,
   --len(qq.FilePath) - charindex('/', reverse(qq.FilePath)) as positionoflastslash
   from old_database.dbo.QuizQuestion qq
   left join old_database.dbo.QuizQuestionType qqt on qq.QuizQuestionTypeID = qqt.QuizQuestionTypeID
   left join old_database.dbo.QuizQuestionDifficulty qqd on qq.QuizQuestionDifficultyID = qqd.QuizQuestionDifficultyID
   left join old_database.dbo.QuizQuestionCategory qqc on qq.QuizQuestionCategoryID = qqc.QuizQuestionCategoryID
   left join old_database.dbo.QuizQuestionDecade qqdc on qq.QuizQuestionDecadeID = qqdc.QuizQuestionDecadeID
   left join old_database.dbo.QuizQuestionCategory qqmc on qq.MasterCategoryID = qqmc.MasterQuestionCategoryID
   left join old_database_Demo.dbo.QuizCategories cat on qqc.CategoryName = cat.name
   left join old_database_Demo.dbo.QuizDifficulties qd on qd.id = qq.MasterDifficultyID
   where qq.MasterCategoryID is not null
) as questions
left join new_database.dbo.Media2 media on media.name = REPLACE(fname,'QUIZ','')

起初我正在

Msg 537, Level 16, State 2, Line 2
Invalid length parameter passed to the LEFT or SUBSTRING function.
The statement has been terminated.

所以我添加了从行尾移动媒体并将其放在答案旁边 并调整选择列表以匹配,因为这是表的结构

--Specify the database, table and columns we want to insert into
INSERT INTO new_database.dbo.QuizQuestions (uuid, [type], question, answer,  media, created_date, modified_date,
master_category, master_decade, master_difficulty, is_editable, is_deletable)

--Get the data from the old database (old_database) and map the media filename to the media2 table in the new database

select 
   questions.uuid, 
   questions.newtype, 
   questions.QuestionText, 
   questions.AnswerText,
   media.id as mediaid, 
   questions.CreatedDate, 
   questions.ModifiedDate, 
   questions.master_category, 
   questions.master_decade, 
   questions.master_difficulty,
   questions.IsEditable, 
   questions.IsDeletable,

 from
(
   select NEWID() as uuid, 
   CASE 
          WHEN qqt.TypeName = 'Sound' THEN 'Audio'
          ELSE qqt.TypeName
   END AS newtype,
   qq.QuestionText, qq.AnswerText, 
   qq.CreatedDate, 
   CASE 
          WHEN qq.ModifiedDate is NOT NULL THEN qq.ModifiedDate
          ELSE GETDATE()
   END as ModifiedDate, 
   CASE
          WHEN cat.id is NOT NULL THEN cat.id
          ELSE 1
   END as master_category,
   qqdc.QuizQuestionDecadeID as master_decade,
   qd.id as master_difficulty,
   qq.IsEditable, qq.IsDeletable,
   qq.FilePath,
   SUBSTRING(
          qq.FilePath, 
          len(qq.FilePath) - charindex('/', reverse(qq.FilePath)) + 2, 
          (len(qq.FilePath) - charindex('.', reverse(qq.FilePath))) - (len(qq.FilePath) - charindex('/', reverse(qq.FilePath))) - 1) as fname
   --len(qq.FilePath) - charindex('.', reverse(qq.FilePath)) as positionoflastdot,
   --len(qq.FilePath) - charindex('/', reverse(qq.FilePath)) as positionoflastslash
   from old_database.dbo.QuizQuestion qq
   left join old_database.dbo.QuizQuestionType qqt on qq.QuizQuestionTypeID = qqt.QuizQuestionTypeID
   left join old_database.dbo.QuizQuestionDifficulty qqd on qq.QuizQuestionDifficultyID = qqd.QuizQuestionDifficultyID
   left join old_database.dbo.QuizQuestionCategory qqc on qq.QuizQuestionCategoryID = qqc.QuizQuestionCategoryID
   left join old_database.dbo.QuizQuestionDecade qqdc on qq.QuizQuestionDecadeID = qqdc.QuizQuestionDecadeID
   left join old_database.dbo.QuizQuestionCategory qqmc on qq.MasterCategoryID = qqmc.MasterQuestionCategoryID
   left join old_database_Demo.dbo.QuizCategories cat on qqc.CategoryName = cat.name
   left join old_database_Demo.dbo.QuizDifficulties qd on qd.id = qq.MasterDifficultyID
   where qq.MasterCategoryID is not null
) as questions
left join new_database.dbo.Media2 media on media.name = REPLACE(fname,'QUIZ','')

现在当我执行im getting

Msg 156, Level 15, State 1, Line 19
Incorrect syntax near the keyword 'from'.
Msg 156, Level 15, State 1, Line 55
Incorrect syntax near the keyword 'as'.

这是我目前卡住的地方,并且不知道如何向前推进以使其正确执行并且我用谷歌搜索和研究分配我甚至有我们的客户数据库人员处理访问看看和他只是像我一样困惑。

任何帮助告诉我哪里出错我会很棒

最好的问候 担

2 个答案:

答案 0 :(得分:0)

我将研究子串函数中Len和Charindex函数的结果。

也许在单独的查询中回显它们。 “无效长度”错误表示正在使用不正确的条件搜索字符串的一部分。

例如..

    len(qq.FilePath) - charindex('/', reverse(qq.FilePath)) + 2

如果是

的结果
charindex('/', reverse(qq.FilePath)) + 2

大于......

的结果
len(qq.FilePath)

然后你将尝试使用负数找到字符串(子字符串)的一部分 - 所以如果上面的结果是-2,例如,你将要求从FilePath中找到-2个字符...这是您传递给substring的无效长度参数。

我会跑这个......

Select   
len(qq.FilePath) - charindex('/', reverse(qq.FilePath)) + 2 as 'SubStrStartPos', 
(len(qq.FilePath) - charindex('.', reverse(qq.FilePath))) - (len(qq.FilePath) - charindex('/', reverse(qq.FilePath))) - 1 as 'NoOfChars'

from old_database.dbo.QuizQuestion qq
 left join old_database.dbo.QuizQuestionType qqt on qq.QuizQuestionTypeID = qqt.QuizQuestionTypeID
 left join old_database.dbo.QuizQuestionDifficulty qqd on qq.QuizQuestionDifficultyID = qqd.QuizQuestionDifficultyID
left join old_database.dbo.QuizQuestionCategory qqc on qq.QuizQuestionCategoryID = qqc.QuizQuestionCategoryID
left join old_database.dbo.QuizQuestionDecade qqdc on qq.QuizQuestionDecadeID = qqdc.QuizQuestionDecadeID
left join old_database.dbo.QuizQuestionCategory qqmc on qq.MasterCategoryID = qqmc.MasterQuestionCategoryID
left join old_database_Demo.dbo.QuizCategories cat on qqc.CategoryName = cat.name
left join old_database_Demo.dbo.QuizDifficulties qd on qd.id = qq.MasterDifficultyID
where qq.MasterCategoryID is not null

并检查结果的负值,排除故障并修改子字符串。

答案 1 :(得分:0)

我设法通过将from放在选择列表的末尾而不是在下面来使查询工作,

select emp.*
from emp
join dept_emp
on dept_emp.emp_no = emp.emp_no
and dept_no = 'd002'

并在子查询上从select questions.uuid, questions.newtype, questions.QuestionText, questions.AnswerText, media.id as mediaid, questions.CreatedDate, questions.ModifiedDate, questions.master_category, questions.master_decade, questions.master_difficulty, questions.IsEditable, questions.IsDeletable from ( 更改为-1以删除任何负值

-0

但它没有正确映射媒体文件并将null返回到新表中的媒体列,但我可以解决这个问题。

感谢所有发帖求助的人。