0

我正在做一些有意义的简单的事情,

IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'TF' AND name = 'GetGeographyFromSourceID')
BEGIN
    DROP FUNCTION dbo.GetGeographyFromSourceID
END
GO

CREATE FUNCTION dbo.GetGeographyFromSourceID
(
    @SourceID INT
)
RETURNS  GEOGRAPHY
AS
BEGIN
    DECLARE @Longitude FLOAT = 0; 
    DECLARE @Latitude FLOAT = 0; 
    DECLARE @Geo GEOGRAPHY;

    SELECT  @Longitude = Longitude, 
            @Latitude = Latitude 
    FROM    Sources 
    WHERE   ID = @SourceID; 

    SELECT @Geo = geography::STGeomFromText('POINT(' + CONVERT(VARCHAR( 100), @Longitude) + ' ' + CONVERT( VARCHAR( 100),@Latitude) + ')', 4326);

    RETURN(@Geo)
END

如果存在,则删除它并重新创建它。但我收到错误There is already an object named 'XXX' in the database?

4

4 回答 4

5

您正在测试数据库中是否存在表值函数,但您描述的函数不返回表。用这个替换代码的第一部分(在开始之前),然后重试:

IF EXISTS (
    SELECT * FROM sysobjects WHERE id = object_id(N'GetGeographyFromSourceID') 
    AND xtype IN (N'FN', N'IF', N'TF')
)
    DROP FUNCTION GetGeographyFromSourceID
GO
于 2013-02-27T15:42:16.380 回答
4

看起来它实际上并没有击中您的 DROP FUNCTION 语句,因为您正在检查xtype = 'TF'哪个只查找此未尝试的表函数xtype='FN'(标量函数)

MSDN 参考

于 2013-02-27T15:42:36.833 回答
3

将其更改为 FN 而不是 TF

IF EXISTS(SELECT * FROM sysobjects WHERE xtype = 'FN' AND name = 'GetGeographyFromSourceID')
BEGIN
    DROP FUNCTION dbo.GetGeographyFromSourceID
END
GO

CREATE FUNCTION dbo.GetGeographyFromSourceID
(
    @SourceID INT
)
RETURNS  GEOGRAPHY
AS
BEGIN
    DECLARE @Longitude FLOAT = 0; 
    DECLARE @Latitude FLOAT = 0; 
    DECLARE @Geo GEOGRAPHY;

    SELECT  @Longitude = Longitude, 
            @Latitude = Latitude 
    FROM    Sources 
    WHERE   ID = @SourceID; 

    SELECT @Geo = geography::STGeomFromText('POINT(' + CONVERT(VARCHAR( 100), @Longitude) + ' ' + CONVERT( VARCHAR( 100),@Latitude) + ')', 4326);

    RETURN(@Geo)
END
于 2013-02-27T15:42:30.770 回答
1

我知道这已经得到了回答,但只是为了补充一点。鉴于 SQL 处理对象名称的方式,通常最好不要在使用此类代码时进行检查。创建对象时,它的名称是唯一的,而不是名称+类型的组合。还有一种更简单的检查方法是使用 OBJECT_ID 函数。这是我在主数据库上做的几个例子。

IF (OBJECT_ID('sysobjects') IS NOT NULL)
    PRINT OBJECT_ID('sysobjects')

IF (OBJECT_ID('sys.sysobjects') IS NOT NULL)
    PRINT OBJECT_ID('sys.sysobjects')

IF (OBJECT_ID('xyz') IS NOT NULL)
    PRINT OBJECT_ID('xyz')

前两个将评估为 true 并运行打印(给出相同的对象 id),第三个将评估为 false 不运行打印。

于 2013-02-27T15:55:27.510 回答