2009-10-19 78 views
3

我有四个表:消息,MessageCategory,MessageStatus和MessageLevel。插入来自多个表的数据

MessageCategory,MessageStatus和MessageLevel都只有三个字段:标识(主键),代码和描述。消息引用这三个字段,并有几个其他数据字段,包括标识(主键)MessageText和Order。身份字段是自动递增的字段。

我现在需要编写一个SQL脚本来为所有四个表添加一些默认数据。问题是,我需要创建一个脚本,将其发送给将执行此脚本的客户。我无法编写更智能的代码来完成整个更新。虽然三个表只是简单的插入语句,但它是Messages表,这引起我一些额外的麻烦。

我不能删除任何指标,我不能假设它开始从1开始为主键计数。

所以,作为一个例子,她的一些数据:

INSERT INTO MessageCategory (Code) Values ('Cat01'); 
INSERT INTO MessageStatus (Code) Values ('Status01'); 
INSERT INTO MessageLevel (Code) Values ('Level01'); 

而且消息将需要的东西是这样的:

INSERT INTO Messages(Category, Status, Level, MessageText, Order) 
VALUES(
    (SELECT Identity from MessageCategory where Code='Cat01'), 
    (SELECT Identity from MessageStatus where Code='Status01'), 
    (SELECT Identity from MessageLevel where Code='Level01'), 
    'Just some message', 
    1 
); 

这是行不通的,虽然。那么,有什么诀窍让这个工作? (保持代码的可读性...)

不幸的是,我没有访问其他数据库。我可以测试它,但一旦它似乎工作,这只是一个发送和祈祷它的工作的问题...

回答

6
INSERT INTO Messages 
    (Category, Status, Level, MessageText, [Order]) 
SELECT 
    (SELECT TOP 1 [Identity] from MessageCategory where Code='Cat01') AS Category, 
    (SELECT TOP 1 [Identity] from MessageStatus where Code='Status01') AS Status, 
    (SELECT TOP 1 [Identity] from MessageLevel where Code='Level01') AS Level, 
    (SELECT 'Just some message') AS MessageText, 
    (SELECT 1)      AS [Order] 

以上将适用于SQL Server。请注意,IdentityOrder都是保留的T-SQL关键字,不应用于列名。还要注意,子查询不得返回多于一行,以确保我已包含TOP 1语句。

接下来要注意的是,列别名(AS Category等)不是严格必要的。他们的顺序是重中之重。为了便于阅读,我会包括它们,尤其是当SELECT列表变长时。

+0

我倾向于在我的SQL脚本用方括号[]周围的所有表和字段名称。这解决了可能的冲突。我倾向于使用更多的保留字作为字段和表名,因此添加括号对我来说是一种自动操作。 :-) – 2009-10-19 12:58:26

+0

所以你应该在你的示例代码中做到这一点。以及。 ;-) – Tomalak 2009-10-19 13:01:55

+0

是的,我希望那些括号会混淆一些,所以我实际上删除了它们。 :-) – 2009-10-19 14:45:03

4

如果它是一个脚本,存储您的身份变量:

declare MessageCategoryID int; 
declare MessageStatusID int; 
declare MessageLevel int; 
INSERT INTO MessageCategory (Code) Values ('Cat01'); 
set @MessageCategoryID=scope_identity(); 
INSERT INTO MessageStatus (Code) Values ('Status01'); 
set @MessageStatudID=scope_identity(); 
INSERT INTO MessageLevel (Code) Values ('Level01'); 
set @MessageLevelID=scope_identity(); 

INSERT INTO Messages(Category, Status, Level, MessageText, Order) 
    VALUES(
     @MessageCAtegoryID, 
     @MessageStatusID, 
     @MessageLevelID, 
     'Just some message', 
     1); 
+0

它是一个单独的脚本,但在Messages表中会有几十个记录。 – 2009-10-19 12:55:07

+4

而不是使用@@ identity使用scope_identity。如果将触发器添加到表中,@@身份可能会导致严重的数据完整性问题。 – HLGEM 2009-10-19 13:10:47

+0

从未使用scope_identity(),但从现在开始。谢谢你的提示! – Kendrick 2009-10-19 15:45:55