car*_*son 12 sql-server configuration recursive
如何更改系统范围的默认值MAXRECURSION
?
默认情况下它是 100,但我需要将它增加到 1000 之类的东西。
我无法使用查询提示,因为我正在使用一个程序来获取我的查询并为我执行它,而且我无法绕过这个限制,不幸的是。
但是,我确实拥有服务器实例的管理员权限。我已经浏览了服务器方面,但我没有看到任何与查询选项或递归相关的内容。我认为必须有一个地方可以更新系统范围的默认值。
有任何想法吗?
Pau*_*ite 10
如果您的查询具有共同的形状,您可以使用一个或多个计划指南添加所需的 maxrecursion 提示。
可以有一个诀窍让他们正确。如果您在问题中添加了特定的查询详细信息,我们或许能够为您解决这个问题。通常,您会跟踪实际访问服务器的 SQL,或使用内置过程sys.sp_get_query_template获取参数化表单,然后创建 TEMPLATE 和/或 OBJECT/SQL 计划指南。
有关更多信息,请参阅文档:
每当应用程序代码更改时,以及修补或升级 SQL Server 时,都需要重新验证计划指南。这应该只是您正常测试周期的一部分。
请注意,如果引导语句引用临时表,则使用sys.fn_validate_plan_guide 的计划指南验证可能会错误地报告失败。看到这个问题:
使用 fn_validate_plan_guide 进行计划指南验证会产生误报
该计划指南成功和计划指南不成功的探查和扩展事件类也可以用来监测计划指南应用程序。
在Steve Kass提出的产品改进建议允许 MAXRECURSION 限制值不是 100 的视图和 UDF之前,Connect 已停用。如果您想立即与 Microsoft 合作,请参阅SQL Server 帮助和反馈中的选项。
如果你绝对必须使用一个函数(你暗示的 ETL 工具的限制),你可以指定OPTION
为多语句表值函数的一部分,例如这样的:
CREATE FUNCTION dbo.udf_MyFunction ( @StartID INT )
RETURNS @tv TABLE
(
id INT
)
AS
BEGIN
WITH Episodes( xlevel, PersonID, EventID, EpisodeID, StartDT, EndDT ) AS (
-- Anchor case - the first EventID for each person.
SELECT 1 AS xlevel, PersonID, EventID, @StartID, StartDT, EndDT
FROM dbo.EventTable
WHERE EventID = @StartID
UNION ALL
SELECT xlevel + 1, et.PersonID, et.EventID, c.EventID + 1, et.StartDT, et.EndDT
FROM Episodes c
INNER JOIN dbo.EventTable et ON c.PersonID = et.PersonID
AND et.EventID = c.EventID + 1
--WHERE c.EventID <= (@StartID + 99)
)
INSERT INTO @tv
SELECT PersonID
FROM Episodes
OPTION ( MAXRECURSION 1000 )
RETURN
END
GO
Run Code Online (Sandbox Code Playgroud)
正如您建议的 ETL 工具所做的那样,当包裹在视图中时,这也对我有用。没有办法在系统范围内改变这个,但由于递归可能效率低下,这可能是一件好事。您不能OPTION
在内联表值函数的主体内指定查询提示(使用),如您的示例所示。
当您收到剧集并将输出存储在关系表中时,请考虑更改您的流程以仅遍历层次结构一次。您可以使用存储过程来执行此操作,因此不会遇到此限制。
我还认为您的代码中可能存在错误:如果您的 CTE 在 personId 上加入并在 eventId 上递归,那么我认为 eventId 101 会出现两次,作为重复。可能我误解了你的代码,让我知道你的想法。
HTH
我从这个话题中得到了灵感。
这是我为解决问题所做的事情。
CREATE FUNCTION MySchema.udf_MyFunction(@StartID INT)
RETURNS TABLE
AS RETURN
WITH
Episodes(PersonID, EventID, EpisodeID, StartDT, EndDT) AS (
-- Anchor case - the first EventID for each person.
SELECT PersonID, EventID, @StartID, StartDT, EndDT
FROM MySchema.EventTable
WHERE EventID = @StartID
UNION ALL
SELECT
...
WHERE
EventID <= (@StartID + 99)
)
SELECT * FROM Episodes
Run Code Online (Sandbox Code Playgroud)
然后我像这样调用这个函数:
WITH
Episodes AS (
SELECT * FROM MySchema.udf_MyFunction(1)
UNION ALL
SELECT * FROM MySchema.udf_MyFunction(101)
UNION ALL
SELECT * FROM MySchema.udf_MyFunction(201)
-- ...
UNION ALL
SELECT * FROM MySchema.udf_MyFunction(901)
)
SELECT * FROM Episodes
Run Code Online (Sandbox Code Playgroud)
这样,我的 CTE 逻辑就不需要重复,而且我也不需要在性能方面支付任何额外费用。必须这样做确实很麻烦,但我可以忍受。
归档时间: |
|
查看次数: |
3090 次 |
最近记录: |