我的任务是将组织的Oracle SQL视图迁移到SQL Server。对于SQL,我是一个新手,并且无法弄清楚我从CASE语句中得到的错误。
在CASE声明中,我想读取字段的值,它将是一个街道地址,例如123 Main St.计划从字段中删除'St'子字符串,并返回'123 Main'< / p>
它已经在Oracle中运行了,我只是将语法转换为SQL Server有困难,SUBSTRING和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
我得到的错误是:
错误来源:.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'
附近的语法不正确
答案 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