CASE语句错误

时间:2014-06-18 15:43:45

标签: sql sql-server

我的任务是将组织的Oracle SQL视图迁移到SQL Server。对于SQL,我是一个新手,并且无法弄清楚我从CASE语句中得到的错误。

在CASE声明中,我想读取字段的值,它将是一个街道地址,例如123 Main St.计划从字段中删除'St'子字符串,并返回'123 Main'< / p>

它已经在Oracle中运行了,我只是将语法转换为SQL Server有困难,SUBSTRINGCASE上的文档没有帮助我解决问题。我可能忽略了一些非常简单的事情。

代码是:

SELECT c.objectid, p.SHAPE, c.APN_PARCEL_NO AS prc_parcel_no, b.addr_status, b.addr_st_nmbr AS st_number, b.addr_st_frac AS st_fraction, b.addr_st_pfx AS st_prefix
CASE 
  WHEN SUBSTRING (b.addr_st_name,  CHARINDEX( ' ', b.addr_st_name, -1) + 1) = 'ALY' 
    THEN SUBSTRING (b.addr_st_name, 1, CHARINDEX( ' ', b.addr_st_name, -1) -1)
  ELSE b.add_st_name
END
FROM dbo.PARCEL AS p INNER JOIN dbo.TBL_APN_PARCEL_LINK AS c ON p.PRC_PARCEL_NO = c.LAND_APN INNER JOIN dbo.TBL_SITE_ADDRESS_ALL AS b ON c.APN_PARCEL_NO = b.prc_parcel_no

我得到的错误是:

  

错误来源:.Net SqlClient数据提供程序

     

错误消息:关键字“CASE”

附近的语法不正确

我为任何格式化问题道歉,仍在学习如何正确编写SQL。为方便起见,Oracle中的CASE语句代码为:

CASE
             WHEN SUBSTR (b.addr_st_name,
                          INSTR (b.addr_st_name, ' ', -1) + 1
                         ) = 'ALY'
                THEN SUBSTR (b.addr_st_name,
                             1,
                             INSTR (b.addr_st_name, ' ', -1) - 1
                            )
   ELSE b.addr_st_name
          END st_name,

tl; dr - 想要将Oracle视图转换为SQL Server,错误是:

  

关键字'CASE'

附近的语法不正确

3 个答案:

答案 0 :(得分:1)

您的CASE声明之前似乎缺少逗号。

另外,在旁注中,您可能会澄清CASE这样的声明:

SELECT c.objectid, p.SHAPE, c.APN_PARCEL_NO AS prc_parcel_no, b.addr_status, b.addr_st_nmbr AS st_number, b.addr_st_frac AS st_fraction, b.addr_st_pfx AS st_prefix,

       CASE SUBSTR (b.addr_st_name, INSTR(b.addr_st_name, ' ', -1) + 1)
         WHEN 'ALY'
           THEN SUBSTR (b.addr_st_name, 1, INSTR (b.addr_st_name, ' ', -1) - 1)
         ELSE b.addr_st_name
       END st_name,

  FROM dbo.PARCEL AS p INNER JOIN dbo.TBL_APN_PARCEL_LINK AS c ON p.PRC_PARCEL_NO = c.LAND_APN INNER JOIN dbo.TBL_SITE_ADDRESS_ALL AS b ON c.APN_PARCEL_NO = b.prc_parcel_no

CASE上的MSDN参考:http://msdn.microsoft.com/en-us/library/ms181765.aspx

答案 1 :(得分:1)

错误是:

Incorrect syntax near the keyword 'CASE'

在你的陈述中,你有:

SELECT c.objectid, p.SHAPE, c.APN_PARCEL_NO AS prc_parcel_no, b.addr_status, b.addr_st_nmbr AS st_number, b.addr_st_frac AS st_fraction, b.addr_st_pfx AS st_prefix
CASE 
  WHEN SUBSTRING (b.addr_st_name,  CHARINDEX( ' ', b.addr_st_name, -1) + 1) = 'ALY' 
    THEN SUBSTRING (b.addr_st_name, 1, CHARINDEX( ' ', b.addr_st_name, -1) -1)
  ELSE b.add_st_name
END
FROM dbo.PARCEL AS p INNER JOIN dbo.TBL_APN_PARCEL_LINK AS c ON p.PRC_PARCEL_NO = c.LAND_APN INNER JOIN dbo.TBL_SITE_ADDRESS_ALL AS b ON c.APN_PARCEL_NO = b.prc_parcel_no

CASE语句是一个返回的新列,但就在它之前,您没有逗号将新列与上一列分开:

...b.addr_st_pfx AS st_prefix /*Insert comma here*/ CASE ...

当然,错误消息没有帮助,但至少它是特定的:错误是“接近CASE”,因为它正好在它之前。可能还有其他问题,但这是错误消息中引用的问题。

我可以看到的另一个问题是ELSE子句中的列名拼写错误:您有add_st_name,应该是addr_st_name

CASE语句本身也似乎将INSTR转换为CHARINDEX时出现问题。 CHARINDEX的最后一个参数是起始位置,但负值等于0:它从字符串的开头开始。 Oracle INSTR使用负位置向后搜索。有关在TSQL中查找最后一个字符(在本例中为空格)的技术,请参阅https://stackoverflow.com/a/9479899

我认为你要做的是:

SELECT c.objectid, p.SHAPE, c.APN_PARCEL_NO AS prc_parcel_no, b.addr_status,
  b.addr_st_nmbr AS st_number, b.addr_st_frac AS st_fraction,
  b.addr_st_pfx AS st_prefix,
  CASE
    WHEN RIGHT(b.addr_st_name, NULLIF(CHARINDEX(' ', REVERSE(b.addr_st_name)), 0) - 1) = 'ALY'
      THEN SUBSTRING(b.addr_st_name, 1, LEN(b.addr_st_name) - CHARINDEX(' ', REVERSE(b.addr_st_name)))
    ELSE b.addr_st_name
  END
FROM dbo.PARCEL AS p
INNER JOIN dbo.TBL_APN_PARCEL_LINK AS c ON p.PRC_PARCEL_NO = c.LAND_APN
INNER JOIN dbo.TBL_SITE_ADDRESS_ALL AS b ON c.APN_PARCEL_NO = b.prc_parcel_no

如果它存在,则从b.addr_st_name剥离“(空格)ALY”的结尾。不太熟悉Oracle,但我认为这就是你原来的声明所做的。

答案 2 :(得分:1)

你缺少一个逗号和一个SUBSTRING字符,我在第一个SUBSTRING和CASE语句之前的逗号中添加了1(你需要检查它应该是什么)。

SELECT c.objectid, p.SHAPE,
 c.APN_PARCEL_NO AS prc_parcel_no, b.addr_status, b.addr_st_nmbr AS st_number,
  b.addr_st_frac AS st_fraction, b.addr_st_pfx AS st_prefix,
CASE 
  WHEN SUBSTRING (b.addr_st_name, 1,  CHARINDEX( ' ', b.addr_st_name, -1) + 1) = 'ALY' 
    THEN SUBSTRING (b.addr_st_name, 1, CHARINDEX( ' ', b.addr_st_name, -1) -1)
  ELSE b.add_st_name
END
FROM dbo.PARCEL AS p INNER JOIN dbo.TBL_APN_PARCEL_LINK AS c ON p.PRC_PARCEL_NO = c.LAN