T-SQL将字符串插入text数据类型列

时间:2016-09-15 17:35:18

标签: sql-server tsql

我有一个T-SQL存储过程,我需要将参数的值插入表中的文本字段。通过参数传入的值实际上是一个查询,我稍后将其作为动态SQL执行。当我输入一行没有任何引号或其他特殊字符如破折号( - )时,它可以正常工作。但是由于引号或特殊字符会引发它,因此引用或引用特殊字符。

存储过程的输入参数是:

@input_query text

我的价值是:

Select 
    t1.*, t2.name 
from 
    nyc..sellers t1 
right join 
    ark..buyers t2 on t1.id = t2.id
where 
    t1.date = 'period' 
    and t2.period between '2016-01-01' and '2016-12-31' 
    and t2.def = 'u'

当我尝试执行这样的存储过程时:

DECLARE @return_value int

EXEC @return_value = [dbo].[booksellers]
     @input_query = N'Select t1.*, t2.name from nyc..sellers t1 right join ark..buyers t2 on
  t1.id = t2.id where t1.date = 'period' and t2.period between '2016-01-01' and '2016-12-31' and t2.def = 'u''

SELECT  'Return Value' = @return_value

我收到以下错误:

  

在'期间'附近不正确的语法

我意识到这是因为引号没有被转义,即使它们是,下一个错误将是日期没有被转义等等。但我不能搞乱那个输入查询 - 它需要按原样插入。有没有办法让它发挥作用?

1 个答案:

答案 0 :(得分:0)

答案是逃避撇号,如果要将文本分配给变量或插入数据库,则必须完成。

转义由查询解析器处理,而不是由处理器处理。当您查看使用转义撇号插入的数据或从数据库中检索它时,您可以使用单撇号将其返回。它不会影响您的数据。

如果我理解正确,您将该查询插入表中,以便以后可以查询该表并执行这些查询。排队报告程序的一些痛处?

这个概念证明查询证明了这可以用ESCAPED APOSTROPHES。我没有你的架构所以我不得不更改表的名称 它创建必要的表和模拟书店过程,将ESCAPED input_query插入表中。用3个不同的查询重复3次。然后我使用临时表和while循环来拉取这些查询并执行它们。

drop table t1;
create table t1 (
    name varchar( 20 ), 
    id varchar( 20 ), 
    date varchar( 20 ), 
    rid int identity primary key
)
drop table t2;
create table t2 (
    name varchar( 20 ),
    id varchar( 20 ), 
    [period] datetime, 
    def varchar( 10 ),
    rid int identity primary key
)
drop table QueryData;
create table QueryData (
    query nvarchar(max), 
    rid int identity primary key
)
go
---- drop procedure dbo.booksellers; 
go
create procedure dbo.booksellers (
    @input_query nvarchar(max)
)
as
begin
declare @return int
insert into QueryData ( query ) values ( @input_query )

select @return = SCOPE_IDENTITY()
return @return
end
go

insert  into t1 ( name, id, date ) values 
    ( 'row1', 'some', 'period' ), 
    ( 'row2', 'more', 'period' ), 
    ( 'row3', 'even', 'not period' )

insert  into t2 ( name, id, [period], def ) values 
    ( 'period1', 'some', '2016-09-15 06:00', 'u' ), 
    ( 'period2', 'more', '2016-09-15 07:00', 'u' ), 
    ( 'period3', 'less', '2017-09-15 06:00', 'u' ),
    ( 'period1', 'some', '2017-09-15 06:00', 'u' ), 
    ( 'period2', 'more', '2017-09-15 07:00', 'u' ), 
    ( 'period3', 'less', '2017-09-15 06:00', 'u' ),
    ( 'period1', 'some', '2017-09-15 06:00', 'x' ), 
    ( 'period2', 'more', '2017-09-15 07:00', 'x' ), 
    ( 'period3', 'less', '2017-09-15 06:00', 'x' )

DECLARE @return_value int
declare @input_query nvarchar(max)
set @input_query =  N'Select t1.*, t2.name from t1 t1 right join t2 t2 on
  t1.id = t2.id where t1.date = ''period'' and t2.period between ''2016-01-01'' and ''2016-12-31'' and t2.def = ''u'''

EXEC @return_value = [dbo].[booksellers]  @input_query
print 'query'
exec sp_executesql @input_query
SELECT  'Return Value' = @return_value

set @input_query = N'Select t1.*, t2.name from t1 t1 right join t2 t2 on
  t1.id = t2.id where t1.date = ''period'' and t2.period between ''2017-01-01'' and ''2017-12-31'' and t2.def = ''u'''

EXEC @return_value = [dbo].[booksellers]  @input_query
exec sp_executesql @input_query
SELECT  'Return Value' = @return_value

set @input_query = N'Select t1.*, t2.name from t1 t1 right join t2 t2 on
  t1.id = t2.id where t1.date = ''period'' and t2.period between ''2017-01-01'' and ''2017-12-31'' and t2.def = ''x'''
EXEC @return_value = [dbo].[booksellers] @input_query
exec sp_executesql @input_query
SELECT  'Return Value' = @return_value


select 'Queued Queries', * from QueryData
declare @queries table (
    queryId int, 
    rid int identity
)

insert into @queries ( queryId )
    select rid from QueryData

declare @row int
declare @queryId int
declare @queryText nvarchar(max)

select @row = max(rid) from @queries
while @row > 0
begin
    select @queryId = queryId from @queries where rid = @row
    select @queryText = query from QueryData where rid = @queryId
    select @queryText
    exec sp_executesql @input_query
    delete @queries where rid = @row
    set @row = @row -1
end