Oli*_*ini 4 sql-server optimization
I'm having a problem specifying a value within an OPTIMIZE FOR
statement. I'd like to optimize the query with the value as a string, but I must be doing something wrong, because SQL gives the following error:
在 OPTIMIZE FOR 子句中为变量“@test”指定的值无法隐式转换为该变量的类型。
下面的示例有点人为,但问题与我在实际查询中遇到的问题相同。
declare @TEMP table(asWord nvarchar(max), asNumber int)
insert into @TEMP (asWord, asNumber) values (
'one',
1
), (
'two',
2
)
DECLARE @test nvarchar(max)
SET @test = 'one'
select * from @TEMP
where asWord = @test
OPTION (OPTIMIZE FOR(@test = 'one'))
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
这是因为您将@test
变量声明为nvarchar(max)
并将其与OPTIMIZE FOR
子句中的非 lob 文字进行比较。
从文档开始OPTIMIZE FOR
:
OPTIMIZE FOR ( _@variable\_name_ { UNKNOWN | = literal_constant } [ , ...n ] )
Run Code Online (Sandbox Code Playgroud)
您应该将变量的长度更改为将存储在其中的值的最大可能字符长度的大小。
DECLARE @test nvarchar(3);
Run Code Online (Sandbox Code Playgroud)
NVARCHAR(MAX)
和 OPTIMIZE FOR
理论上,您可以针对nvarchar(max)
字段进行优化,但似乎文字必须超过4000
(for nvarchar
) 个字符长:
创建 4000 个空间时:
SELECT REPLICATE(' ', 4000);
Run Code Online (Sandbox Code Playgroud)
并将它们添加到常量的末尾:
declare @TEMP table(asWord nvarchar(max), asNumber int)
insert into @TEMP (asWord, asNumber) values (
'one',
1
), (
'two',
2
)
DECLARE @test nvarchar(max)
SET @test = 'one'
select * from @TEMP
where asWord = @test
OPTION (OPTIMIZE FOR(@test = N'one ' ))
Run Code Online (Sandbox Code Playgroud)
它也有效。
您不能使用CAST()
或CONVERT()
显式将常量更改为NVARCHAR(MAX)
DB<>Fiddle
额外的
如果变量小于nvarchar(max)
但常量结束4000
(对于nvarchar
)字符,它仍然有效。:
declare @TEMP table(asWord nvarchar(max), asNumber int)
insert into @TEMP (asWord, asNumber) values (
'one',
1
), (
'two',
2
)
DECLARE @test nvarchar(3)
SET @test = 'one'
select * from @TEMP
where asWord = @test
OPTION (OPTIMIZE FOR(@test = N'one ' ))
Run Code Online (Sandbox Code Playgroud)
因为文字值之后的所有空格都被“截断”,并且被视为 nvarchar(3):
<ColumnReference Column="@test" ParameterCompiledValue="N'one'" ParameterRuntimeValue="N'one'" />
Run Code Online (Sandbox Code Playgroud)
如果我们将变量更改为 nvarchar(4)
DECLARE @test nvarchar(4)
Run Code Online (Sandbox Code Playgroud)
另一个空间存在于 ParameterCompiledValue
<ColumnReference Column="@test" ParameterCompiledValue="N'one '" ParameterRuntimeValue="N'one'" />
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
199 次 |
最近记录: |