我想在SQL中创建一个函数,但是我遇到了很多错误

时间:2016-12-06 07:44:43

标签: sql sql-server

我想在Management Studio中的SQL Server中创建函数:

Input: 7589586586     Output:  (758) 958-6586
Input: 758ABC6586     Output: (758) 222-6586  
Input: 758ABC65       Output: Invalid Formats (like mobile keypad)

这是我的SQL代码,我遇到了很多错误:

CREATE FUNCTION fn_bhagyashreed_phonenumber
    (@input VARCHAR(20))
RETURNS VARCHAR(50)
BEGIN
    DECLARE @compare VARCHAR(30) = '';            
    DECLARE @cnt INT = 1;
    DECLARE @varout VARCHAR(30) = '';
    DECLARE @val VARCHAR(30) = '';
    DECLARE @Phoutput VARCHAR(50) = '';
    DECLARE @var INT;

    SET @var = LEN(@input);

    IF @var <> 10 OR @input NOT REGEXP '^[[:alnum:]]+$' THEN
        SET @Phoutput = 'Invalid Format';
    ELSE
        WHILE @cnt <= 10 
        BEGIN
            SET @compare = SUBSTRING(@input, @cnt, 1);

            IF @compare IN('a','b','c','2') 
            BEGIN
                SET @val=2;
            ELSE IF @compare IN('d', 'e', 'f', '3') 
            BEGIN
                SET @val=3;
            ELSE IF @compare IN('g', 'h', 'i', '4') 
            BEGIN
                SET @val = 4;
            ELSE IF @compare IN('j', 'k', 'l', '5') 
            BEGIN
                SET @val = 5;
            ELSE IF @compare IN('m', 'n', 'o', '6') 
            BEGIN
                SET @val = 6;
            ELSE IF @compare IN('p', 'q', 'r', 's', '7') 
            BEGIN
                SET @val = 7;
            ELSE IF @compare IN('t', 'u', 'v', '8') 
            BEGIN
                SET @val = 8;
            ELSE IF @compare IN('w', 'x', 'y', 'z', '9') 
            BEGIN
                SET @val = 9;
            ELSE IF @compare = '1' 
            BEGIN
                SET @val = 1;
            ELSE IF @compare = '0' 
            BEGIN
                SET @val = 0;
        END 

        SET @varout = CONCAT(@varout,@val);
        SET @cnt = @cnt + 1;
    END;

    SET @Phoutput = CONCAT('(',SUBSTRING(@varout,1,3),')',' ',SUBSTRING(@varout,4,3),'-',SUBSTRING(@varout,7,4));
END; IF;
RETURN Phoutput;
END$$

这些是错误:

  

Msg 102,Level 15,State 1,Procedure fn_bhagyashreed_phonenumber,Line 13
  “REGEXP”附近的语法不正确。

     

Msg 156,Level 15,State 1,Procedure fn_bhagyashreed_phonenumber,Line 15
  关键字“ELSE”附近的语法不正确。

     

Msg 156,Level 15,State 1,Procedure fn_bhagyashreed_phonenumber,Line 20
  关键字“ELSE”附近的语法不正确。   .......

4 个答案:

答案 0 :(得分:3)

你的整个方法远离 sql thinking 。您可以执行此过程,但SQL(如果可能)最好使用 set based

完全尝试 ad-hoc SQL

System.loadLibrary("awt")

结果

DECLARE @tbl TABLE(ID INT IDENTITY,phoneString VARCHAR(100));
INSERT INTO @tbl VALUES('7589586586'),('758ABC6586'),('758ABC65');

WITH tenDigits AS (SELECT Nr FROM(VALUES(1),(2),(3),(4),(5),(6),(7),(8),(9),(10)) AS x(Nr))
,Splitted AS
(
    SELECT ID 
          ,Nr
          ,CASE WHEN SUBSTRING(phoneString,Nr,1) IN('a','b','c','2') THEN '2'
                WHEN SUBSTRING(phoneString,Nr,1) IN('d','e','f','3') THEN '3'
                WHEN SUBSTRING(phoneString,Nr,1) IN('g','h','i','4') THEN '4'
                WHEN SUBSTRING(phoneString,Nr,1) IN('j','k','l','5') THEN '5'
                WHEN SUBSTRING(phoneString,Nr,1) IN('m','n','o','6') THEN '6'
                WHEN SUBSTRING(phoneString,Nr,1) IN('p','q','r','s','7') THEN '7'
                WHEN SUBSTRING(phoneString,Nr,1) IN('t','u','v','8') THEN '8'
                WHEN SUBSTRING(phoneString,Nr,1) IN('w','x','y','z','9') THEN '9'
                WHEN SUBSTRING(phoneString,Nr,1) ='1' THEN '1'
                WHEN SUBSTRING(phoneString,Nr,1) ='0' THEN '0'
                ELSE 'X'
            END AS Digit
    FROM @tbl AS t
    CROSS JOIN tenDigits
)
,ReConcatenated AS
(
    SELECT s.ID
          ,'(' 
          + STUFF(STUFF(
           (SELECT x.Digit AS [*] 
            FROM Splitted AS x 
            WHERE s.ID=x.ID 
            ORDER BY Nr
            FOR XML PATH('')
           ),4,0,') '),9,0,'-') AS PhoneNumber
    FROM Splitted AS s
    GROUP BY ID
)
SELECT *
      ,CASE WHEN CHARINDEX('X',PhoneNumber)>0 THEN 'Invalid Format' ELSE PhoneNumber END AS Validated
FROM ReConcatenated

简短说明

首先,我创建一个表变量到模拟测试场景。第一个CTE ID PhoneNumber Validated 1 (758) 958-6586 (758) 958-6586 2 (758) 222-6586 (758) 222-6586 3 (758) 222-65XX Invalid Format 将创建一个从1到10运行的派生表。第二个CTE将返回一个派生表,其中phonenumber的数字逐个,它将在同一个过程中做必要的替换。第三个CTE将单个数字与一个文本进行协调。 tenDigits用于将STUFF)推送到正确的位置。最后存在一个&#39; X&#39;表示无效的号码。

如果-超过10,您可以将第一个CTE增加到10个以上,并添加X以消除长数的错误。

答案 1 :(得分:0)

这里有多个语法错误,我不会单独检查它们。

每个IF必须有BEGINEND

IF condition1
BEGIN
    -- Do stuff
END
ELSE 
BEGIN 
    IF condition2
    BEGIN
        -- Do Stuff
    END
    ELSE
    BEGIN
        IF condition3
        BEGIN
            -- Do stuff
        END
    END
END

https://msdn.microsoft.com/en-us/library/ms182587.aspx#Examples(例D)

END$$应为END

答案 2 :(得分:0)

这应该有效

CREATE FUNCTION fn_bhagyashreed_phonenumber(@input VARCHAR(20))
RETURNS VARCHAR(50)
  BEGIN
    DECLARE @compare VARCHAR(30) = ''
    DECLARE @cnt INT = 1
    DECLARE @varout VARCHAR(30) = ''
    DECLARE @val VARCHAR(30) = ''
    DECLARE @Phoutput VARCHAR(50) = ''
    DECLARE @var INT

    SET @var = LEN(@input)

    IF @var <> 10
        OR @input LIKE '%[^a-z0-9-'']%'
      SET @Phoutput = 'Invalid Format'
    ELSE
      BEGIN
        WHILE @cnt <= 10
          BEGIN
            SET @compare = SUBSTRING(@input, @cnt, 1)
            SET @val=CASE
                       WHEN @compare IN ('a', 'b', 'c', '2') THEN 2
                       WHEN @compare IN ('d', 'e', 'f', '3') THEN 3
                       WHEN @compare IN ('g', 'h', 'i', '4') THEN 4
                       WHEN @compare IN ('j', 'k', 'l', '5') THEN 5
                       WHEN @compare IN ('m', 'n', 'o', '6') THEN 6
                       WHEN @compare IN ('p', 'q', 'r', 's', '7') THEN 7
                       WHEN @compare IN ('t', 'u', 'v', '8') THEN 8
                       WHEN @compare IN ('w', 'x', 'y', 'z', '9') THEN 9
                       WHEN @compare IN ('1') THEN 1
                       WHEN @compare IN ('0') THEN 0
                       ELSE 0
                     END
            SET @varout = CONCAT(@varout, @val)
            SET @cnt = @cnt + 1
          END
      END

    IF @Phoutput <> 'Invalid Format'
      BEGIN
        SET @Phoutput = CONCAT('(', SUBSTRING(@varout, 1, 3), ')', ' ', SUBSTRING(@varout, 4, 3), '-', SUBSTRING(@varout, 7, 4))
      END

    RETURN @Phoutput
  END 

答案 3 :(得分:0)

我只是想与众不同。 尝试使用其他样本数据。

DECLARE @tbl TABLE(ID INT IDENTITY,phoneString VARCHAR(100));
INSERT INTO @tbl VALUES('7589586586'),('758ABC6586'),('758ABC65')

;With CTE as
(
select id,replace(phoneString,char(97),'2') phoneString,97 rn 
from @tbl where phoneString like '%[Aa-Zz]%' and len(phoneString)=10

union all

select id, replace(phoneString,char(rn)
,case when rn BETWEEN 97 and 99 then '2' 
when rn BETWEEN 100 and 102 then '3' 
when rn BETWEEN 103 and 105 then '4' 
when rn BETWEEN 106 and 108 then '5' 
when rn BETWEEN 109 and 111 then '6' 
when rn BETWEEN 112 and 114 then '7' 
when rn BETWEEN 115 and 117 then '8' 
when rn BETWEEN 119 and 122 then '9' 
else 'X' end),rn+1 from cte c
where rn<122 and phoneString like '%[Aa-Zz]%'

)
,CTE1 as
(
select  *,ROW_NUMBER()over( partition by id order by rn desc) rn1 
from cte    
)

select id,phonestring,'('+SUBSTRING(phonestring,1,3)+' ) '+ 
SUBSTRING(phonestring,4,3)+'-'+SUBSTRING(phonestring,8,3)
 Validated from cte1
where rn1=1
union ALL
select id,phonestring,'('+SUBSTRING(phonestring,1,3)+' ) '+ 
SUBSTRING(phonestring,4,3)+'-'+SUBSTRING(phonestring,8,3)
 Validated from @tbl
where isnumeric(phoneString)=1 and len(phoneString)=10
union ALL
select id,phonestring,'invalid format' from @tbl 
where len(phonestring)<10