我有一个无法控制的(MS)SQL VIEW,它还查询了我无法控制但必须使用的其他几个SQL VIEW。
根据“pilot”值获取所有行,除非它以402或403或A40开头。只要所有“pilot”条目都可以解释为INT,这是当前查询正常工作。
SELECT * from sqlsrvlink.DATABASE.dbo.V_PILOT_GENERAL WHERE NOT LEFT(pilot,3) IN ('402','403')
该试验应该始终是一个INT,但SQL设计需要很多,并且实现为VARCHAR。因此,对于没有输入格式检查的3:rd方应用程序,可以“配置”“pilot”列以不包含任何数值,在这种情况下,我的SELECT语句失败并显示错误消息:
Msg 245,Level 16,State 1,Line 1 语法错误将varchar值'A406XX'转换为数据类型为int的列。
如何扩展SELECT以排除A40,但主要通过排除或直接忽略它们来解决'将VARCHAR转换为INT'的问题(无数值)。
答案 0 :(得分:2)
SELECT * from sqlsrvlink.DATABASE.dbo.V_PILOT_GENERAL
WHERE pilot NOT LIKE '402%' AND pilot NOT LIKE '403%' AND pilot NOT LIKE 'A40%'
应该更好地利用飞行员的任何指数
修改强>
根据你的评论,我认为我最初误解了这个问题。问题不在于SELECT语句本身,而是当无效数据在基表中时,更多的尝试访问违规行中的该列会导致如下错误。
CREATE VIEW [dbo].[testing]
AS
SELECT 1 AS [Number]
,'X' AS Letter
union all
SELECT 'bob' AS [Number]
,'Y' AS Letter
union all
SELECT 3 AS [Number]
,'Z' AS Letter
GO
SELECT * /*Works*/
FROM [dbo].[testing]
WHERE Letter IN ('X', 'Z')
SELECT CAST([Number] AS varchar(10)) /*Error Occurs*/
FROM [dbo].[testing]
我不知道有什么方法可以避免这种情况而不改变View定义(你说你不能做)或更改基础数据,或者重写查询以不使用视图。您将无法过滤该列以删除狡猾的记录,因为尝试在过滤器中使用它只会导致错误发生。
答案 1 :(得分:1)
这可能没问题。我觉得你的'NOT'在左边走了一点......
SELECT *
FROM sqlsrvlink.DATABASE.dbo.V_PILOT_GENERAL
WHERE LEFT(pilot,3) NOT IN ('402','403', 'A40');
答案 2 :(得分:1)
这样的事情怎么样?这适用于字符串/文本字段。
SELECT * from sqlsrvlink.DATABASE.dbo.V_PILOT_GENERAL WHERE pilot not like(402%) or ...