Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/85.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.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无效标识符错误_Sql_Sql Server_Sql Server 2008 R2 - Fatal编程技术网

SQL无效标识符错误

SQL无效标识符错误,sql,sql-server,sql-server-2008-r2,Sql,Sql Server,Sql Server 2008 R2,我有一个执行select语句的函数。当我尝试执行此select语句时,该语句返回一个值并将其设置为一个变量,我的函数会崩溃,出现以下错误: Msg 203,16级,状态2,程序信息\u GetWholeNumber,第20行 名称“选择最大长度(铸造(地板([pcom\U audit\u cant\u con])作为 VARCHAR(38)))作为一个整体,Auditorias.prod\u com\u audit“不是 有效标识符 如果我复制并粘贴select语句,效果会很好。。。因此,这不是

我有一个执行select语句的函数。当我尝试执行此select语句时,该语句返回一个值并将其设置为一个变量,我的函数会崩溃,出现以下错误:

Msg 203,16级,状态2,程序信息\u GetWholeNumber,第20行
名称“选择最大长度(铸造(地板([pcom\U audit\u cant\u con])作为 VARCHAR(38)))作为一个整体,Auditorias.prod\u com\u audit“不是 有效标识符

如果我复制并粘贴select语句,效果会很好。。。因此,这不是选择,它与我的执行有关。。。无论如何,这是我的函数代码

ALTER FUNCTION [dbo].[Info_GetWholeNumber]
(
    @TABLE VARCHAR(MAX)
    , @COLUMN VARCHAR(MAX)
)
RETURNS INT
AS
BEGIN
    -- Declare the return variable here
    DECLARE @WHOLE_NO INT

    -- Add the T-SQL statements to compute the return value here
    DECLARE @SQL VARCHAR(MAX)
    SET @SQL = 'SELECT MAX(LEN(CAST(FLOOR([' + @COLUMN + ']) AS VARCHAR(38))))
      AS WHOLE_NO FROM ' + @TABLE
    EXEC @WHOLE_NO = @SQL

    -- Return the result of the function
    RETURN @WHOLE_NO

END
如果有人对我如何解决这个问题有任何想法,我将非常感谢您的帮助!提前谢谢

更新:

好的,我正试图使用前面提到的sp_executesql函数,我将粘贴新函数

ALTER FUNCTION [dbo].[Info_GetWholeNumber]
(
@TABLE VARCHAR(MAX)
, @COLUMN VARCHAR(MAX)
)
RETURNS INT
AS
BEGIN
DECLARE @WHOLE_NO INT
DECLARE @SQL NVARCHAR(MAX)
DECLARE @PARAMS NVARCHAR(MAX)

SET @SQL = N'SELECT @WHOLE_NOOUT = MAX(LEN(CAST(FLOOR(@COL) AS VARCHAR(38)))) FROM @TBL'
SET @PARAMS = N'@COL VARCHAR(MAX), @TBL VARCHAR(MAX), @WHOLE_NOOUT INT OUTPUT'

EXECUTE sp_executesql @SQL, @PARAMS, @COL = @COLUMN, @TBL = @TABLE, @WHOLE_NOOUT = @WHOLE_NO OUTPUT;

-- Return the result of the function
RETURN @WHOLE_NO

END
我现在得到这个错误:

Msg 1087,第16级,状态1,第1行 必须声明表变量“@TBL”


在我看来这似乎是正确的,因为变量不是在@PARAM变量中声明的。。。我在这里遗漏了什么吗?

拉马克是对的。不能在函数中执行存储过程(或任何能够更新、插入、删除的操作)

ALTER FUNCTION [dbo].[Info_GetWholeNumber]
(
@TABLE VARCHAR(MAX)
, @COLUMN VARCHAR(MAX)
)
RETURNS INT
AS
BEGIN
DECLARE @WHOLE_NO INT
DECLARE @SQL NVARCHAR(MAX)
DECLARE @PARAMS NVARCHAR(MAX)

SET @SQL = N'SELECT @WHOLE_NOOUT = MAX(LEN(CAST(FLOOR(@COL) AS VARCHAR(38)))) FROM @TBL'
SET @PARAMS = N'@COL VARCHAR(MAX), @TBL VARCHAR(MAX), @WHOLE_NOOUT INT OUTPUT'

EXECUTE sp_executesql @SQL, @PARAMS, @COL = @COLUMN, @TBL = @TABLE, @WHOLE_NOOUT = @WHOLE_NO OUTPUT;

-- Return the result of the function
RETURN @WHOLE_NO

END
函数应该是只读的


你可能想考虑使用一个存储过程代替你的函数。

< P> Lamak是正确的。不能在函数中执行存储过程(或任何能够更新、插入、删除的操作)

ALTER FUNCTION [dbo].[Info_GetWholeNumber]
(
@TABLE VARCHAR(MAX)
, @COLUMN VARCHAR(MAX)
)
RETURNS INT
AS
BEGIN
DECLARE @WHOLE_NO INT
DECLARE @SQL NVARCHAR(MAX)
DECLARE @PARAMS NVARCHAR(MAX)

SET @SQL = N'SELECT @WHOLE_NOOUT = MAX(LEN(CAST(FLOOR(@COL) AS VARCHAR(38)))) FROM @TBL'
SET @PARAMS = N'@COL VARCHAR(MAX), @TBL VARCHAR(MAX), @WHOLE_NOOUT INT OUTPUT'

EXECUTE sp_executesql @SQL, @PARAMS, @COL = @COLUMN, @TBL = @TABLE, @WHOLE_NOOUT = @WHOLE_NO OUTPUT;

-- Return the result of the function
RETURN @WHOLE_NO

END
函数应该是只读的


你可能想考虑使用一个存储过程代替你的函数。

< P>你既不能直接从一个Exchange语句分配,也不能直接从一个<代码> Exc< /Cord>d动态SQL中分配变量(超出范围)。这也不应该真正从函数中调用,因为SQL期望函数是确定性的,而事实并非如此(事实上,即使修复了错误,它也可能不起作用)

ALTER FUNCTION [dbo].[Info_GetWholeNumber]
(
@TABLE VARCHAR(MAX)
, @COLUMN VARCHAR(MAX)
)
RETURNS INT
AS
BEGIN
DECLARE @WHOLE_NO INT
DECLARE @SQL NVARCHAR(MAX)
DECLARE @PARAMS NVARCHAR(MAX)

SET @SQL = N'SELECT @WHOLE_NOOUT = MAX(LEN(CAST(FLOOR(@COL) AS VARCHAR(38)))) FROM @TBL'
SET @PARAMS = N'@COL VARCHAR(MAX), @TBL VARCHAR(MAX), @WHOLE_NOOUT INT OUTPUT'

EXECUTE sp_executesql @SQL, @PARAMS, @COL = @COLUMN, @TBL = @TABLE, @WHOLE_NOOUT = @WHOLE_NO OUTPUT;

-- Return the result of the function
RETURN @WHOLE_NO

END
假设更改了调用此代码的方式,则需要知道如何从动态sql中获取值。如果要从动态SQL字符串传递变量,则必须将
EXEC SP\u ExecuteSQL
与输出参数一起使用

下面是一个简单的例子:

DECLARE @whole_no int;
DECLARE @SQL nvarchar(500);
DECLARE @Parms nvarchar(500);;

SET @SQL = N'SELECT @whole_noOUT = 1';
SET @Parms = N'@whole_noOUT int OUTPUT';

EXECUTE sp_executesql @SQL, @Parms, @whole_noOUT=@whole_no OUTPUT;
SELECT @WHOLE_NO;
在本例中,我们将设置一个参数定义和一个输出参数。一般来说,
sp_executesql
是调用动态sql的首选方法,因为它可以参数化,这既可以通过避免直接连接sql来提高安全性,也可以在sql完全参数化时允许计划重用

我还应该补充一个强制性的警告,即无论是现在还是将来,您都不应该像对待sql注入那样漫不经心地构建动态sql。我知道您不能参数化特定的查询,但至少您应该在列名上使用
QUOTENAME()
,而不是对
[]
进行硬编码

请在此处阅读有关sp_executesql的更多信息:
有关
QUOTENAME()
的更多信息,请参见:

您既不能直接从EXEC语句赋值,也不能直接从
EXEC
d动态SQL内部赋值变量(超出范围)。这也不应该真正从函数中调用,因为SQL期望函数是确定性的,而事实并非如此(事实上,即使修复了错误,它也可能不起作用)

假设更改了调用此代码的方式,则需要知道如何从动态sql中获取值。如果要从动态SQL字符串传递变量,则必须将
EXEC SP\u ExecuteSQL
与输出参数一起使用

下面是一个简单的例子:

DECLARE @whole_no int;
DECLARE @SQL nvarchar(500);
DECLARE @Parms nvarchar(500);;

SET @SQL = N'SELECT @whole_noOUT = 1';
SET @Parms = N'@whole_noOUT int OUTPUT';

EXECUTE sp_executesql @SQL, @Parms, @whole_noOUT=@whole_no OUTPUT;
SELECT @WHOLE_NO;
在本例中,我们将设置一个参数定义和一个输出参数。一般来说,
sp_executesql
是调用动态sql的首选方法,因为它可以参数化,这既可以通过避免直接连接sql来提高安全性,也可以在sql完全参数化时允许计划重用

我还应该补充一个强制性的警告,即无论是现在还是将来,您都不应该像对待sql注入那样漫不经心地构建动态sql。我知道您不能参数化特定的查询,但至少您应该在列名上使用
QUOTENAME()
,而不是对
[]
进行硬编码

请在此处阅读有关sp_executesql的更多信息:
更多关于
QUOTENAME()
的信息,请点击此处:

您不能在计算机上使用
EXEC
function@Lamak在我的例子中,由于select语句是动态的…,我将如何执行它?您仍然不能使用
EXECUTE
sp_executesql
或调用函数中的任何其他存储过程。为什么这需要是一个函数?您不能在计算机上使用
EXEC
function@Lamak在我的例子中,由于select语句是动态的…,我将如何执行它?您仍然不能使用
EXECUTE
sp_executesql
或调用函数中的任何其他存储过程。为什么这需要是一个函数?我刚刚更新了我的问题,我在尝试你的建议,但现在又出现了一个错误。你知道为什么吗?@Lord Link你不能像那样参数化表和列。在调用
sp_executesql
so:
SET@SQL=N'SELECT@WHOLE_NOOUT=MAX(LEN(CAST(FLOOR('+QUOTENAME(@COLUMN)+')AS VARCHAR(38)))之前,您需要将它们构建到SQL字符串中,然后从'+QUOTENAME(@TABLE)
的参数定义中删除它们。这样,您将只参数化输出变量。好吧,这似乎做了一些正确的事情,因为我没有得到一个错误。。。我的问题被卡住了,但我会检查一下,看看我是否能找出原因。。。谢谢你的帮助,谢谢你,很抱歉我反应迟钝