Anstatt OPTION (QUERYTRACEON 9481) zu verwenden, wird hier eine Lösung / Problemumgehung vorgeschlagen.
Es ermöglicht einem Nicht-Sa-Benutzer, den Kardinalitätsschätzer für die bestimmte Anweisung, Abfrage oder Prozeduraufruf (für die aktuelle Sitzung) zu ändern.
Lösung:
Wunderbar erklärt von Kimberly Tripp in ihrem Beitrag auf sqlskills.com:
"Festlegen von CE-TraceFlags auf Abfrage-für-Abfrage- (oder Sitzungs-) Basis"
Erstellen Sie eine gespeicherte Prozedur in der msdb-Datenbank, mit der ein gewünschtes Trace-Flag ohne Sysadmin-Berechtigungen festgelegt werden kann.
(Natürlich kümmert sich sysadmin darum, eine Liste der zulässigen Trace-Flag-Werte einzurichten.)
Schließen Sie alle problematischen Anweisungen (dynamisches SQL, Ad-hoc-Abfrage oder Prozeduraufruf) mit einem Aufruf dieser gespeicherten Prozedur ab und ändern Sie das Sitzungsablaufverfolgungsflag für die Ausführung.
Auf diese Weise können Benutzer mit niedrigeren Berechtigungen den Kardinalitätsschätzer für die Ausführung der problematischen Anweisung ändern.
Anwendungsbeispiel:
EXEC msdb.dbo.msdbSetTraceFlag 9481, 1;
GO
Problematic STATEMENT or PROCEDURE
EXEC msdb.dbo.msdbSetTraceFlag 9481, 0; -- don't remember to turn it back off!
GO
Code für gespeicherte Prozeduren:
USE msdb;
GO
CREATE PROCEDURE msdbSetTraceFlag
(@TraceFlag int,
@OnOff bit = 0)
WITH EXECUTE AS OWNER
AS
DECLARE @OnOffStr char(1) = @OnOff;
-- Sysadmins can add supported trace flags and then use this
-- from their applications
IF @TraceFlag NOT IN (
9481 -- LegacyCE if database is compat mode 120 or higher
, 2312 -- NewCE if database compat mode 110 or lower
)
BEGIN
RAISERROR('The Trace Flag supplied is not supported. Please contact your system administrator to determine inclusion of this trace flag: %i.', 16, 1, @TraceFlag);
RETURN
END
ELSE
BEGIN
DECLARE @ExecStr nvarchar(100);
IF @OnOff = 1
SELECT @ExecStr = N'DBCC TRACEON(' + CONVERT(nvarchar(4), @TraceFlag) + N')';
ELSE
SELECT @ExecStr = N'DBCC TRACEOFF(' + CONVERT(nvarchar(4), @TraceFlag) + N')';
-- SELECT (@ExecStr)
EXEC(@ExecStr)
-- RAISERROR (N'TraceFlag: %i has been set to:%s (1 = ON, 0 = OFF).', 10, 1, @TraceFlag, @OnOffStr);
END;
GO
GRANT EXECUTE ON msdbSetTraceFlag TO PUBLIC --or to a specific set of users;
GO
Hinweis: Diese gespeicherte Prozedur wird in msdb und nicht auf dem Master erstellt, da für msdb die "vertrauenswürdige" Voraussetzung erforderlich ist.
SELECT * FROM <yourTableName> option (querytraceon 9481)