我在我的网络应用中添加了“标记”功能。我的应用程序表结构如下:
Tag:
(TagId INT IDENTITY, TagName VARCHAR(60))
TaggedRecords:
(TaggedId INT IDENTITY, TagId, TaggedRecordId)
现在,我希望当有人向任何记录添加标记时,应该使用单个sql查询或使用存储过程执行以下操作;
基本上,我更感兴趣的是使用单个查询或最多两个sql查询来执行这些操作。我不想在sql存储过程中创建多个If-Else条件。
谢谢,
答案 0 :(得分:1)
你基本上已经掌握了它,但你可以通过改变顺序使其更有效率。这是您的过程的一些伪SQL代码:
SELECT TagId FROM Tag WHERE TagName = @NewTag into @TagId
IF @TagId IS NULL THEN
INSERT new tag, returning the new TagId into @TagId
INSERT new record into TaggedRecords
不确定为什么你对使用if子句如此不利......
要将新生成的TagId放入变量中,我们有两个选项,因为您使用的是MSSQL:
INSERT INTO Tag (TagName) OUTPUT Inserted.TagId INTO @TagId VALUES (@NewTag);
INSERT INTO Tag (TagName) VALUES (@NewTag); SELECT TagId FROM Tag WHERE TagName = @NewTag INTO @TagId;
如果要将其退出,如果使用IF EXISTS子句,则该过程可能会更好地读取,但实质上您无论如何都要做同样的工作:
IF NOT EXISTS(SELECT TagId FROM Tag WHERE TagName = @NewTag)
BEGIN
INSERT INTO Tag (TagName) VALUES (@NewTag);
SET @TagId = (SELECT TagId FROM Tag WHERE TagName = @NewTag);
END
ELSE
BEGIN
SET @TagId = (SELECT TagId FROM Tag WHERE TagName = @NewTag);
END
INSERT new record into TaggedRecords
答案 1 :(得分:1)
这个怎么样......
CREATE PROC TagMe(@TagName VARCHAR(100),@TaggedRecordId INT)
AS
DECLARE @TagId INT
SET @TagId = SELECT TagId FROM Tag WHERE TagName = @TagName
IF @TagId IS NOT NULL
BEGIN
--Tag exists
INSERT INTO TaggedRecords (TagId, TaggedRecordId) VALUES(@TagId,@TaggedRecordId)
RETURN
END
ELSE
-- New tag
BEGIN
INSERT INTO Tag (TagName) OUTPUT inserted.id INTO @TagId VALUES(@TagName)
INSERT INTO TaggedRecords (TagId, TaggedRecordId) VALUES(@TagId,@TaggedRecordId)
RETURN
END
没有对此进行测试,但理论应该是合理的:)
有关OUTPUT用法的另一个示例,请参阅this link
上的帖子修改强>
根据以下评论,此版本使用EXISTS ...
CREATE PROC TagMe(@TagName VARCHAR(100),@TaggedRecordId INT)
AS
DECLARE @TagId INT
IF EXISTS(SELECT TagId FROM Tag WHERE TagName = @TagName)
BEGIN
--Tag exists
SET @TagId = SELECT TagId FROM Tag WHERE TagName = @TagName
INSERT INTO TaggedRecords (TagId, TaggedRecordId) VALUES(@TagId,@TaggedRecordId)
RETURN
END
ELSE
-- New tag
BEGIN
INSERT INTO Tag (TagName) OUTPUT inserted.id INTO @TagId VALUES(@TagName)
INSERT INTO TaggedRecords (TagId, TaggedRecordId) VALUES(@TagId,@TaggedRecordId)
RETURN
END
虽然我不确定(我认为我在这里反对自己,但这些东西中有很多是“依赖于”答案!)。这个例子实际上最适合更多地使用新标签,因为它只执行一次EXISTS然后继续,而对于现有标签,它将执行EXISTS然后执行SELECT。
嗯,接受你的选择 - 或在体积下测试两种方法:)
答案 2 :(得分:0)
我可以问为什么? if / else有限制吗? :)
看一下你的情况,它看起来不需要超过1个IF条款。
答案 3 :(得分:0)
您可以在标记表中使用合并,然后在标记记录表中插入。这是Oracle语法,所以你必须调整它,但想法是一样的:
MERGE INTO TAG
USING (SELECT @tagname as TAGNAME FROM DUAL) RECORD
ON (TAG.TAGNAME = RECORD.TAGNAME)
WHEN NOT MATCHED THEN INSERT (TAG.TAGNAME) VALUES (@tagname);
INSERT INTO TAGGEDRECORDS(TAGID) VALUES (SELECT TAGID FROM TAG WHERE TAGNAME=@tagname);
我认为SQL Server在MERGE语句中也支持更多功能,所以你可以用WHEN MATCHED(插入taggedrecords表)子句做一些事情。
退房 MSDN link