我正在处理存储过程,这部分让我感到困惑。
我有City
,Zip
和StateName
列。我需要在表中添加信息,并且应该避免它已经存在。这样就不会在数据库中复制数据。
我有以下代码。请帮助我找出问题所在。
CREATE PROCEDURE dbo.sproc_InsertAddressElements
@City nvarchar(100),
@Zip nvarchar(10),
@State nvarchar(40)
AS
BEGIN
SET NOCOUNT ON
IF NOT EXISTS (Select c.[Name] FROM Cities c WHERE c.[Name]=@City)
INSERT INTO Cities ([Name])
VALUES (@City)
ELSE IF EXISTS (Select c.[Name] FROM Cities c WHERE c.[Name]=@City)
IF NOT EXISTS (Select z.ZipCode FROM ZipCodes z WHERE z.ZipCode=@Zip)
INSERT INTO ZipCodes(ZipCode)
VALUES (@Zip)
IF NOT EXISTS (Select s.[Name] FROM States s WHERE s.[Name]=@State)
INSERT INTO States([Name])
VALUES (@State)
END
GO
根据我的理解,我已经创建并编写了一个过程。但是它没有按预期工作。
答案 0 :(得分:1)
根据给定的信息,我认为这更像您的追求。
CREATE PROCEDURE dbo.sproc_InsertAddressElements
@City nvarchar(100)
,@Zip nvarchar(10)
,@State nvarchar(40)
AS
BEGIN
SET NOCOUNT ON
IF NOT EXISTS (Select 1 FROM Cities c WHERE c.[Name]=@City)
Begin
INSERT INTO Cities ([Name])
VALUES (@City)
End
IF NOT EXISTS (Select 1 FROM ZipCodes z WHERE z.ZipCode=@Zip)
Begin
INSERT INTO ZipCodes(ZipCode)
VALUES (@Zip)
End
IF NOT EXISTS (Select 1 FROM States s WHERE s.[Name]=@State)
Begin
INSERT INTO States([Name])
VALUES (@State)
End
END
您可能要考虑其他一些数据验证步骤,但这应该使您朝着正确的方向前进。
养成也正确使用Begin
和End
语句的习惯,以便控制流按预期工作。
答案 1 :(得分:1)
先做检查然后再作出反应的危险是,在此期间可能要经过另一个过程,并导致意外的重复。您可以通过在支票和插入项周围添加事务,并确保选中的行在此期间被锁定来解决此问题。或者,您可以将check和insert in 1查询结合起来(并仍然进行锁定),因为它们将在隐式事务下工作。
类似的东西
CREATE PROCEDURE dbo.sproc_InsertAddressElements
@City nvarchar(100)
,@Zip nvarchar(10)
,@State nvarchar(40)
AS
BEGIN
SET NOCOUNT ON
INSERT INTO Cities ([Name])
SELECT [Name] = @City
WHERE NOT EXISTS (Select c.[Name] FROM Cities c WITH (UPDLOCK) WHERE c.[Name]=@City)
INSERT INTO ZipCodes(ZipCode)
SELECT ZipCode = @Zip
WHERE NOT EXISTS (Select z.ZipCode FROM WITH (UPDLOCK) ZipCodes z WHERE z.ZipCode=@Zip)
INSERT INTO States([Name])
SELECT [Name] = @state
WHERE NOT EXISTS (Select s.[Name] FROM States s WITH (UPDLOCK) WHERE s.[Name]=@State)
END
GO
答案 2 :(得分:0)
邮政编码和城市也固有地包含重复项。我想问一个城市如何在没有所有条目的情况下与一组邮政编码和州相关联。
但是,是的,您只需要摆脱@Allenman指出的那行。