我正在尝试调用一个接受可空参数的sql函数-从动态SQL语句 。
创建动态语句很困难,因为当参数值为'NULL'时,合并会使整个语句为空。我有以下内容:
SET dynamicQuery =
'select * from [qlik].udf_getStatistic( ''' + @myParameter + ''' )'
上面的示例在@myParameter传递到的存储过程中。它可以为null或字符串值。显然,当它是一个字符串时,需要用引号引起来,但当它为null时,一定不能用引号引起来。如下:
select * from [qlik].udf_getStatistic( 'Heights' )
select * from [qlik].udf_getStatistic( NULL )
这个问题同样适用于调用存储过程,该存储过程接受来自动态SQL的可为空的参数。 这些示例来自SQL Server。
答案 0 :(得分:1)
答案实际上在存储过程和函数之间是不同的。
从Books On Line or whatever they call it this month(向下滚动):
当函数的参数具有默认值时,在调用函数以检索默认值时必须指定关键字DEFAULT。此行为与在存储过程中使用具有默认值的参数不同,在存储过程中,省略参数也表示默认值。但是,使用EXECUTE语句调用标量函数时,不需要DEFAULT关键字。
因此对于proc,当您想传递NULL
参数时,就不能传递它。但是,对于一个函数,您必须告诉它明确使用DEFAULT
值。无论哪种方式,都不会为它传递显式的NULL
。幸运的是,对于您的动态SQL,显式DEFAULT
也可用于存储过程。在这两种情况下,为了确保正确分配传递的参数,您需要在调用中使用显式的参数名称。
让我们使用此函数定义:
CREATE FUNCTION (or procedure) [qlik].udf_getStatistic (
@param1 integer = 0,
@param2 varchar(100) = 'foo'
) AS ...
两个参数都是可选的。由于这是一个函数,因此此调用将引发insufficient number of parameters
错误:
select * from [qlik].udf_getStatistic( 'Heights' );
如果它是一个过程调用,它将抛出一个cannot convert value 'Heights' to data type integer
,因为它将唯一的参数值应用到遇到的第一个参数中,该参数期望一个整数。在两种情况下,您都可以通过这种方式获得想要的东西:
select * from [qlik].udf_getStatistic( @param1 = DEFAULT, @param2 = 'Heights' );
这将我们带入您的动态SQL。将您的参数名称添加到静态文本中,然后使用COALESCE
(如果需要,可以使用CASE
)来决定是否传递一个显式值,或进行DEFAULT
调用。>
DECLARE @myParameter1 VARCHAR(100) = 'foo',
@myParameter2 INTEGER,
@SQL NVARCHAR(MAX);
SET @SQL =
'select
*
from [qlik].udf_getStatistic(
@param1 = ''' + COALESCE(@myParameter1, 'DEFAULT') + ''',
@param2 = ' + COALESCE(CAST(@myParameter2 AS VARCHAR(30)),'DEFAULT') + ' );';
SELECT @SQL;
结果:
select * from [qlik].udf_getStatistic( @param1 = 'foo', @param2 = DEFAULT );
答案 1 :(得分:1)
只需使用显式文字from . import views
from django.conf.urls import url
urlpatterns = [
url(r'^$', views.blog_view, name='blog_view'),
]
来对NULL
值进行转义,请确保仅在值不为NULL
时才包括引号。
NULL
您可能希望转义变量中可能包含的其他单引号,将其替换为双单引号,以免破坏动态构建。
答案 2 :(得分:1)
据我了解,我在SQL Server 2012上尝试了此
CREATE PROCEDURE ToNullProc
(@i VARCHAR(20))
AS
BEGIN
PRINT 'you entered ' + @i
END
CREATE FUNCTION ToNullFun
(@i VARCHAR(20))
RETURNS @table TABLE (i VARCHAR(20))
AS
BEGIN
INSERT INTO @table
SELECT ('You entered ' + @i) a
RETURN
END
DECLARE @j VARCHAR(20) = 'Hi',
@QueryFun NVARCHAR(50) = N'',
@QueryProd NVARCHAR(50) = N''
IF @j IS NOT NULL
BEGIN
SET @QueryFun = N'select * from ToNullFun ('''+@j+''')'
SET @QueryProd = N'exec ToNullProc '''+@j+''''
END
ELSE BEGIN
SET @QueryFun = N'select * from ToNullFun ('+@j+')'
SET @QueryProd = N'exec ToNullProc '+@j+''
END
PRINT @queryfun
PRINT @queryprod
EXEC sp_executesql @queryfun
EXEC sp_executesql @queryprod
更新 用于动态过程和动态功能:
create table #temp (Num int identity (1,1), NullVal int)
insert into #temp (NullVal) values (1),(null),(3)
alter proc ToNullProc (
@Operator varchar (max), @NullVal varchar (max)
) as
begin
declare @Query nvarchar (max) = N'select * from #temp where NullVal ' +
@Operator + @NullVal
-- print @query + ' ToNullProc print '
exec sp_executesql @query -- Here we run the select query from Proc
end
create function ToNullFun (
@Operator varchar (max), @NullVal varchar (max)
)
returns nvarchar (max)
as
begin
declare @Query nvarchar (max)
set @Query = N'select * from #temp where NullVal ' + @Operator + @NullVal
/*
I try to into to Table variable by using ITVF,
'insert into @table exec sp_executesql @query'.
But this type of insert is not allowed in ITVF.
*/
return @query
end
declare @NullVal varchar (max) = '1'
, @QueryFun nvarchar (max) = N''
, @QueryProd nvarchar (max) = N''
declare @FunResultTalbe table (
Query nvarchar (100)
) /* To store the result Funtion */
if @NullVal is not null
begin
set @QueryFun = N'select dbo.ToNullFun ('' = '','''+@NullVal+''')'
set @QueryProd = N'exec ToNullProc '' = '','''+@NullVal+''''
end
else begin
set @QueryFun = N'select dbo.ToNullFun ('' is null '','''')'
set @QueryProd = N'exec ToNullProc '' is null '','''''
end
print @queryfun + ' At start'
print @queryprod + ' At start'
exec sp_executesql @queryprod -- It calls Proc
insert into @FunResultTalbe
exec sp_executesql @queryfun -- It calls the Function and insert the query into the table.
set @QueryFun = (select top 1 * from @FunResultTalbe) -- Here we get the query from the table.
print @queryfun
exec sp_executesql @queryfun -- Here we run the select query. Which is dynamic
结果集
-- Result of Procedure
Num NullVal
1 1
-- Result of Function
Num NullVal
1 1
让我知道,你得到了什么。