SO 和其他网站上有多个帖子明确指出了最大长度nvarchar(max)为 2GB。然而,我在互联网和现实生活中也看到了很多混乱,它实际上是 Unicode 中的 8000/4000。
我想知道什么事情可以改变这个事实,或者可能导致某人错误地假设这一点。
我已经收集的一些建议/部分答案:
当将nvarchar(max)变量/列分配给非最大尺寸组件的串联时,我们必须将所有内容都nvarchar(max)显式转换吗?下面展示了一个奇怪的示例,其中文本返回函数需要转换,而文字的 N 可以省略:
declare @s nvarchar(max)
select @s = convert(nvarchar(max), replicate('.', 8000)) + N'Hi!'
select len(@s) -- returns 8003
declare @s nvarchar(max)
select @s = replicate('.', 8000) + N'Hi!'
select len(@s) -- returns 4000
declare @s nvarchar(max)
select @s = convert(nvarchar(max), replicate('.', 8000)) + 'Hi!'
select len(@s) -- returns 8003
Run Code Online (Sandbox Code Playgroud)有办法禁用该功能吗?与此有sp_tableoption @OptionName=large value types out of row …
我们有一个特定的查询,在proc内部运行得慢得多.我必须在这里添加它,它被包含在一个两级游标中.但是,两个游标都有一行的迭代结果集.
让我先说明我们尝试过但失败的事情:
这是从proc/cursors内部获取的查询.
select @tpdim1 = dim1, @tpdim2 = dim2, @typecalc = typecalc
from loyalty_policy where code=@loop2_loyalty_policy
Run Code Online (Sandbox Code Playgroud)
注意:@ loop2_loyalty_policy是取自内部游标结果的var,并且有一个值.code是PK到loyalty_policy桌子.因此,@ tpdim1和@tpdim2各有一个值.
SET STATISTICS PROFILE ON
SET STATISTICS xml on
insert into @tbl_loyal_loop2 (cnt, store, map, pda, insdate, line, item, loyalty_policy_data, loyal_calc, loyalty_policy)
select @cnt, t.store, t.map, t.pda, t.insdate, t.line, t.item, ld.tab_id,
case @typecalc
when 1 then convert(bigint,round(isnull(t.valueFromTran,0.00) * ld.value , 0 ) )
when 2 then convert(bigint,round(isnull(t.netvalue,0.00) * ld.value , 0 ) …Run Code Online (Sandbox Code Playgroud) 在我们的数据库中,大多数表都有一个dbupddate字段指示datetime最后一个INSERT或UPDATE应用于该行。
为了避免该字段具有错误的值,存在触发器(有时AFTER,有时INSTEAD OF)来确保最终该值是正确的,而不是有人尝试写入该字段的任何“手动”其他值。
现在我正在执行更新语句(实际上MERGE),并且我想要一个OUTPUT包含该字段的子句。正如我在相应的 MS 文章中读到的,OUTPUT忽略触发器。
是否有任何解决方法可以返回触发器后的OUTPUT值?dbupddate我不想进行另一个查询来绘制信息,因为我不能保证在这些查询之间的瞬间,另一个用户的第三个查询可能不会改变所有内容。
遵循 Larnu 的建议后的结果
我运行了提供的示例,唯一的例外是将字段default的值更改updatetime为,convert(datetime2,'1900-01-01')以便我可能有意义。我运行了 4 个查询中的每一个,然后从各自的表中进行选择并比较了值updatetime:
INSERT INTO dbo.Sample1 (Someint)
OUTPUT inserted.*
INTO @inserted
SELECT 1;
SELECT 'Sample1 INSERT',*
FROM @inserted; -- 1900-01-01 00:00:00.000000
select * from Sample1 -- 2018-11-05 13:12:13.141580
Run Code Online (Sandbox Code Playgroud)
我猜这里的输出会忽略触发器并返回after触发器生效之前插入的默认值。
DECLARE @inserted table (ID int, Someint int, …Run Code Online (Sandbox Code Playgroud) 我在选择查询上使用这些公式,基于 [Date] 字段。1-6月为1个学期,7-12月为2个学期。季度是 3 个月的版本(1 月至 3 月等为 1 个月)。
case when Month([Date])>=7 then 2 else 1 end as [Semester],
ceiling((Month([Date])-1)/3)+1 as [Quarter]
Run Code Online (Sandbox Code Playgroud)
这些工作,但我想知道是否有一个更简单/更优雅的解决方案(尽管我已经检查了日期时间功能)。
我觉得奇怪的是,带有 ntile() 函数的语言在日期方面没有类似的东西。
我不是 SQL 的高级程序员,也许我的问题很愚蠢,但我还没有在谷歌中找到答案。我们有一些 SQL 结构来实现更改包:
...
BEGIN TRY
BEGIN TRANSACTION;
<User Code Is Here>
...
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
...
END CATCH;
...
Run Code Online (Sandbox Code Playgroud)
如何放置 CREATE TRIGGER 块链而不是<User Code Is Here>没有错误:
-- Table1
CREATE TRIGGER trTable1_Dates ON dbo.Table1
AFTER INSERT, UPDATE
AS
BEGIN
SET NOCOUNT ON;
...
SET NOCOUNT OFF;
END
GO
...
-- TableN
CREATE TRIGGER trTableN_Dates ON dbo.TableN
AFTER INSERT, UPDATE
AS
BEGIN
SET NOCOUNT ON;
...
SET NOCOUNT OFF;
END
GO
Run Code Online (Sandbox Code Playgroud)
目的是创建所有触发器或不创建任何触发器,并在失败时在 CATCH 代码块中打印消息。 …
我正在游标内运行一个过程。经过多次成功的迭代,我得到了这个:
Transaction (Process ID 104) was deadlocked on lock | communication buffer resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
我不会发布完整的详细信息,因此我不期望得到细粒度的调试答案。事实:
select(我看到来自 dm exec 请求的正在运行的查询)如果我的两点没记错的话,是否有可能陷入僵局?死锁是否会要求资源的所有相关用户都对其进行写入操作,这会在资源请求图中创建一个循环?我理解 a 中的超时错误select,但无法理解死锁。我缺少什么?
更新:
我放弃了进一步的调试,因为我注意到我认为存在的索引并不存在。创建时,性能还可以。
然而,为了保持这个有用并希望能找到答案,以下是我调查的更多内容、一些事实和对评论的想法:
首先,sql server版本是2008。我知道这是不支持的。我无法提出建议,更不用说更新服务器了。
我发现 Jeroen Mostert 的评论很有趣。“过去”有多少?我注意到在 sys.dm_os_waiting_tasks 中,会话被自身阻塞多次,且等待类型为 CXPACKET。我做了一些搜索,但选项(maxdop 1)没有解决问题。但是,请记住不存在的索引将导致性能糟糕。难道是附加了正确的并行性,但是操作太多了?尽管如此,我也目睹了巨大的 dm_exec_requests.wait_time。因此,即使查询很糟糕,我还是相信周围存在奇怪的(死)锁。
如果答案/评论提出了跟踪问题的特定查询/步骤,我将很乐意重新创建它。
我有一个 varchar 列,它应该只包含字母和数字,而不能包含其他字符,例如;: , @ 等等
我认为这会起作用,但它不起作用:
select * from table
where field NOT LIKE '[a-z0-9]'
Run Code Online (Sandbox Code Playgroud) 我正在使用sql服务器。
我有一段这样的代码
while(@@rowcount>0)
begin
--do stuff
end
Run Code Online (Sandbox Code Playgroud)
问题是,我想做一些整洁的事情,以确保第一次迭代能够运行。你建议在前面放什么?目前,我已经使用了
select 'Calling this to initialize @@rowcount to 1'
Run Code Online (Sandbox Code Playgroud)
这是不言自明的,但如果有更好的东西,我想知道。
sql-server ×8
t-sql ×8
sql ×3
datetime ×1
nvarchar ×1
regex ×1
transactions ×1
try-catch ×1
while-loop ×1