Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server MSSQL存储过程参数错误:百分比_cont运算符中的数据类型numeric和nvarchar不兼容_Sql Server_Stored Procedures - Fatal编程技术网

Sql server MSSQL存储过程参数错误:百分比_cont运算符中的数据类型numeric和nvarchar不兼容

Sql server MSSQL存储过程参数错误:百分比_cont运算符中的数据类型numeric和nvarchar不兼容,sql-server,stored-procedures,Sql Server,Stored Procedures,昨天当我编写一个看似无害的存储过程时,遇到了一个奇怪的问题。以下是相关的代码片段: Create PROCEDURE [dbo].[TestProc] @Attr1 NVARCHAR(50) = '[Col]' @Calc numeric(3,2) = 0.1 @JobID NVARCHAR(15) = '1' AS BEGIN SET NOCOUNT ON; Select distinct @JobID,

昨天当我编写一个看似无害的存储过程时,遇到了一个奇怪的问题。以下是相关的代码片段:

Create PROCEDURE [dbo].[TestProc]
   @Attr1 NVARCHAR(50)      = '[Col]'
   @Calc numeric(3,2)       = 0.1
   @JobID NVARCHAR(15)      = '1'

   AS
   BEGIN
    SET NOCOUNT ON;

    Select distinct @JobID,

    PERCENTILE_CONT(@Calc)
            within group (order by @Attr1)
            over(partition by @JobID) as S_1_10
from table
where JobID = 1
存储过程停止时出现错误“percentile_cont运算符中的数据类型numeric和nvarchar不兼容”。“at”结束(按@JobID分区)为S_1_10”。我已经知道问题在于@Attr1。如果我将其与列的名称[Col]交换,它就可以正常工作。这里似乎不允许使用变量,但这对我来说毫无意义。我有另一个存储过程,在其中我有完全相同的场景,但我将它构造为一个字符串,并使用sp_executesql执行它


我正在使用MSSQL 2014。感谢您提前提出任何想法

我相信这就是你需要的:

Create PROCEDURE [dbo].[TestProc]
   @Attr1 NVARCHAR(50)      = '[Col]'
   @Calc numeric(3,2)       = 0.1
   @JobID NVARCHAR(15)      = '1'

AS
BEGIN
    SET NOCOUNT ON;
    DECLARE @sql NVARCHAR(200)
    DECLARE @params NVARCHAR(200)

    SET @sql = 'SELECT DISTINCT JobID,  PERCENTILE_CONT('+@Calc+') WITHIN GROUP (ORDER BY '+@Attr1+') OVER(PARTITION BY JobID) AS S_1_10 FROM TABLE WHERE JobID = @JobID'

    SET @params = '@JobID NVARCHAR(15)'

    EXECUTE sp_executesql @sql, @params, @JobID=@JobID
END   

您必须使用动态SQL,但大多数情况下这不是一个好主意-由于代码注入的可能性,您可能希望通过使用而不是

来最小化风险,这在任何数据库中都是不允许的,不仅仅是SQL Server。不能将表名或列名作为字符串名传递,正如不能将C#中整型参数的名称传递给需要整数值的函数一样。另一个存储过程1)是完全不同的,因为它已经有了一个具体的名称,一旦构建2)是一个SQL注入错误。谢谢分享!谢谢你的提示,我应该自己来的。