我有一些问题要将@TableName传递给Nearby程序,以便在一个StoreLocator中使用。我需要进入3个表格。我已经使用QUOTENAME进行了测试,但问题始终存在。有人可以帮我解决这个问题。感谢
ALTER PROCEDURE [dbo].[GetNearbyTable]
@Table sysname,
@CenterLatitude FLOAT,
@CenterLongitude FLOAT,
@SearchDistance FLOAT,
@EarthRadius FLOAT
AS
DECLARE @CntXAxis FLOAT
DECLARE @CntYAxis FLOAT
DECLARE @CntZAxis FLOAT
SET @Table = RTRIM(@Table)
SET @CntXAxis = COS(RADIANS(@CenterLatitude)) * COS(RADIANS(@CenterLongitude))
SET @CntYAxis = COS(RADIANS(@CenterLatitude)) * SIN(RADIANS(@CenterLongitude))
SET @CntZAxis = SIN(RADIANS(@CenterLatitude))
SELECT TOP 100 *,
ProxDistance = @EarthRadius * ACOS( dbo.XAxis(glat, glon)*@CntXAxis + dbo.YAxis(glat, glon)*@CntYAxis + dbo.ZAxis(glat)*@CntZAxis)
FROM @Table
WHERE @EarthRadius * ACOS( dbo.XAxis(glat, glon)*@CntXAxis + dbo.YAxis(glat, glon)*@CntYAxis + dbo.ZAxis(glat)*@CntZAxis) <= @SearchDistance
@Table或QUOTENAME(@Table)不被接受。我已经测试了@Table作为varchar(50)和类似的。我不是SQLexpert。
答案 0 :(得分:2)
SQL Server不允许您从动态表名中进行选择。您需要构建一个nvarchar(max)字符串,并使用exec()
或sp_executesql
。如果可以,为了可维护性和性能原因,无需动态传递表名...
答案 1 :(得分:1)
尝试
exec sp_executesql N'SELECT TOP 100 *, ProxDistance = @EarthRadius * ACOS( dbo.XAxis(glat, glon)*@CntXAxis + dbo.YAxis(glat, glon)*@CntYAxis + dbo.ZAxis(glat)*@CntZAxis)
FROM @Table'
答案 2 :(得分:1)
您需要EXEC()
来执行动态SQL。这应该是您期望的查询:
EXEC('
SELECT TOP 100 *,
ProxDistance = ' + @EarthRadius + ' * ACOS( dbo.XAxis(glat, glon)*'
+ @CntXAxis + ' + dbo.YAxis(glat, glon)*'
+ @CntYAxis + ' + dbo.ZAxis(glat)*'
+ @CntZAxis + ')
FROM ' + QUOTENAME(@Table) + '
WHERE ' + @EarthRadius + ' * ACOS( dbo.XAxis(glat, glon)*'
+ @CntXAxis + ' + dbo.YAxis(glat, glon)*'
+ @CntYAxis + ' + dbo.ZAxis(glat)*'
+ @CntZAxis + ') <= ' + @SearchDistance)
顺便说一句,在生成这样的动态SQL时,请注意SQL注入的可能性(参见http://msdn.microsoft.com/en-us/library/ms161953.aspx)。我写的声明没有注入风险,因为它引用了它包含的唯一字符串。