如何在SQL SELECT语句中压制或忽略错误

6

有人知道如何在select语句中抑制/忽略错误吗?

我的select语句使用STLineFromText函数,当它遇到无效行时会引发错误。我可以忽略错误的行,但实际上不能改变我的源数据。

这是一个演示我问题的示例查询:

SELECT geography::STLineFromText('LINESTRING(-74.2204037952351 40.4283173372472,-74.2204851952350 40.4283519372471)', 4326) UNION ALL
SELECT geography::STLineFromText('LINESTRING(-74.2316367952177 40.4386102038979,-74.2313671952181 40.4388540705641)', 4326) UNION ALL
SELECT geography::STLineFromText('LINESTRING(-74.2229282618978 40.4252709372519,-74.2229171285645 40.4252638039186,-74.2229282618978 40.4252709372519,-74.2227441952315 40.4251499372521,-74.2231121285642 40.4243291372534)', 4326) UNION ALL
SELECT geography::STLineFromText('LINESTRING(-74.2418989952017 40.4417621372263,-74.2417773285352 40.4417915372263)', 4326) UNION ALL
SELECT geography::STLineFromText('LINESTRING(-74.2166069952410 40.4334496039059,-74.2158269952422 40.4336396039056)', 4326)

以下是错误信息:

Msg 6522, Level 16, State 1, Line 2
A .NET Framework error occurred during execution of user-defined routine or aggregate "geography": 
System.ArgumentException: 24200: The specified input does not represent a valid geography instance.
System.ArgumentException: 
   at Microsoft.SqlServer.Types.SqlGeography.ConstructGeographyFromUserInput(GeoData g, Int32 srid)
   at Microsoft.SqlServer.Types.SqlGeography.GeographyFromText(OpenGisType type, SqlChars taggedText, Int32 srid)

理想情况是只返回#1、#2、#4和#5,忽略#3。
谢谢!
2个回答

3

我硬着头皮写了自己的CLR函数,以便能够加入try/catch。目前它运行得非常好。

<Microsoft.SqlServer.Server.SqlFunction()> _
Public Shared Function STLineFromTextFlexible(ByVal LineString As SqlChars, ByVal SRID As Integer) As Microsoft.SqlServer.Types.SqlGeography
    Try
        Dim Geo As New SqlGeography()

        Geo = SqlGeography.STLineFromText(LineString, SRID)

        Return Geo
    Catch ex As Exception
        Return Nothing
    End Try
End Function

Credits:

http://msdn.microsoft.com/en-us/library/w2kae45k(v=vs.80).aspx

http://msdn.microsoft.com/en-us/library/ms131065.aspx


1

不行,回答你的原始问题,你不能简单地让SQL Server“忽略”错误。在服务器端唯一的方法是创建一个UDF,它接受与STLineFromText相同的参数,但将调用包含在try/catch块中,并在出现异常的情况下返回null

好吧,划掉那个,因为你不能在函数中使用try/catch。然而,你可以定义一个UDF,它是对一个带有该值作为参数的存储过程的OPENQUERY调用的传递。然后你可以去喝一杯。

大致如下...

CREATE PROCEDURE SP_IgnoreErrors(@value varchar(255), @param int)
AS
BEGIN
    BEGIN TRY
        SELECT geography::STLineFromText(@value, @param) AS VALUE
    END TRY
    BEGIN CATCH
        SELECT NULL AS VALUE
    END CATCH
END

CREATE FUNCTION IgnoreErrors(@value varchar(255), @param int) RETURNS XXX
AS
BEGIN
    DECLARE @output XXX

    SELECT @output = VALUE from OPENQUERY([YOURINSTANCE],'Database.dbo.SP_IgnoreErrors ''' + @value + ''', ' + convert(varchar, @param))

    RETURN @output
END

这当然是个可怕的事情。虽然我没有 SSMS 在我面前,但即使它不能编译,至少也足够让我们调整成可以编译的东西。


我其实刚刚在回复MainMa时写了同样的建议。 我认为这可能是最好的选择。 我会尝试一下并报告它的工作情况。 - Tom Halladay
太棒了,你不能在UDF内部使用try/catch块。或者任何错误处理方式…… - Tom Halladay
@Tom:虽然我不一定会支持这种做法,但如果你非常想要实现这个功能,你可以创建一个存储过程,将该值作为参数传入,然后在UDF中使用OPENQUERY从其结果中进行选择。这并不是理想的(甚至还很远),但应该能够正常工作。 - Adam Robinson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接