我正在做简单的事情,这是有道理的,
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?
答案 0 :(得分: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
答案 1 :(得分:4)
看起来它实际上并没有达到你的DROP FUNCTION语句,因为你正在检查只查找表函数的xtype = 'TF'
,这个函数不是xtype='FN'
(标量函数)
答案 2 :(得分: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
答案 3 :(得分:1)
我知道这已经得到了回答,但只是为了补充一点。考虑到SQL处理对象名称的方式,通常最好不要检查何时使用这种类型的代码。创建对象时,它的名称是唯一的,而不是名称+类型的组合。另外一种更简单的检查方法是使用OBJECT_ID函数。以下是我在master数据库上做的一些例子。
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并运行print(给出相同的对象id),第三个将评估为false而不运行print。