使用SQL Server 2014中的存储过程更新表

时间:2016-08-10 17:00:32

标签: sql-server tsql

我有两个表,请参阅附加的架构,我写了一个无法正常工作的存储过程。请帮帮我。

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[countries]
(
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [Name] [nvarchar](max) NULL,
    [Prefix] [nvarchar](max) NULL,
    [MinDigits] [int] NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[customers]
(
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [Name] [nvarchar](max) NULL,
    [Business] [nvarchar](max) NULL,
    [Phone] [nvarchar](max) NULL,
    [CountryID] [int] NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

表格中的示例数据:

Id  Name      Business   Phone            CountryID
---------------------------------------------------
 1  John      B&B LLC    001820199202        ***
 2  Mike      ABC Inc    006192479121        ***
 3  Jennifer  Coca Cola  0017421             ***
 4  Sabine    ABC Inc    0091827411          ***
...

国家:

Id   Name          Prefix   MinDigits
--------------------------------------
 1   USA           001        10
 2   Australia     0061       11
 3   India         0091        9
...

我想根据国家/地区表更新customers表中的CountryID

基于以上结果:

Id  Name      Business   Phone            CountryID
---------------------------------------------------
 1  John      B&B LLC    001820199202        1
 2  Mike      ABC Inc    006192479121        2
 3  Jennifer  Coca Cola  0017421             ***
 4  Sabine    ABC Inc    0091827411          3
...

Jennifer的条目未更新,因为最小数字不匹配

这是我的存储过程:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER  PROCEDURE [dbo].[UpdateCustomer]
AS
BEGIN
    SELECT *
    INTO #CustomerTable 
    FROM dbo.customers

    DECLARE @Phone NVARCHAR
    DECLARE @CountryID INT
    DECLARE @Count INT
    DECLARE @CustomerID INT

    WHILE EXISTS (SELECT * FROM #CustomerTable)
    BEGIN
        SELECT TOP 1 
            @Phone = Phone, @CustomerID = Id
        FROM
            #CustomerTable

        IF((SELECT TOP 1 COUNT(*) 
            FROM countries 
            WHERE @Phone LIKE Prefix+'%' And LEN(@Phone) <= MinDigits) > 0)
        BEGIN
            SELECT TOP 1 
                @CountryID = Id 
            FROM
                countries 
            WHERE
                @Phone LIKE Prefix + '%' 
                AND LEN(@Phone) <= MinDigits

            UPDATE customers 
            SET CountryID = @CountryID 
            WHERE Id = @CustomerID
        END

        DELETE #CustomerTable
        WHERE Id = @CustomerID
    END

    DROP TABLE #CustomerTable
END

5 个答案:

答案 0 :(得分:2)

您可以像执行整个存储过程一样执行此类操作

UPDATE  cu
SET     cu.CountryId = co.Id
FROM    customers cu
JOIN    countries co ON cu.phone LIKE co.prefix + '%'
WHERE   LEN(cu.phone) >= co.MinDigits

答案 1 :(得分:1)

但是,如果您想从SP执行此操作,请将@phone变量的大小定义为

DECLARE @Phone NVARCHAR(30) -- as needed

它未保留指定的电话号码,因此更新声明无效。

答案 2 :(得分:0)

使用UPDATE FROM

UPDATE customers
SET CountryID = C.Id   
FROM
     Countries C
WHERE
    LEFT(customers.Phone, LEN(C.Prefix)) = C.Prefix  AND
    LEN(customers.phone) >= C.MinDigits

答案 3 :(得分:0)

首先,SQL是基于的设置,因此使用循环概念并不是最佳选择。

您可以使用MERGE声明:

MERGE customers c
USING countries cs
  ON c.Phone LIKE CONCAT(cs.Prefix, '%')
 AND LEN(c.Phone) >= cs.MinDigits
WHEN MATCHED THEN
  UPDATE 
  SET CountryId = cs.Id;

LiveDemo

答案 4 :(得分:0)

SET ANSI_NULLS ON 走 SET QUOTED_IDENTIFIER ON GO

ALTER PROCEDURE [dbo]。[UpdateCustomer] 如 开始     选择 *     INTO #CustomerTable     来自dbo.customers

DECLARE @Phone NVARCHAR(MAX)
DECLARE @CountryID INT
DECLARE @Count INT
DECLARE @CustomerID INT

WHILE EXISTS (SELECT * FROM #CustomerTable)
BEGIN
    SELECT TOP 1 
        @Phone = Phone, @CustomerID = Id
    FROM
        #CustomerTable

    IF((SELECT TOP 1 COUNT(*) 
        FROM countries 
        WHERE @Phone LIKE Prefix+'%' And LEN(@Phone) >= MinDigits) > 0)
    BEGIN
        SELECT TOP 1 
            @CountryID = Id 
        FROM
            countries 
        WHERE
            @Phone LIKE Prefix + '%' 
            AND LEN(@Phone) >= MinDigits

        UPDATE customers 
        SET CountryID = @CountryID 
        WHERE Id = @CustomerID
    END

    DELETE #CustomerTable
    WHERE Id = @CustomerID
END

DROP TABLE #CustomerTable

END