rax*_*xso 2 sql-server t-sql index-tuning
我在下面的脚本中遇到以下错误
消息 102,级别 15,状态 1,第 44 行
'?' 附近的语法不正确。消息 319,级别 15,状态 1,第 47 行
关键字“with”附近的语法不正确。如果此语句是公共表表达式、xmlnamespaces 子句或更改跟踪上下文子句,则前一条语句必须以分号终止。
任何人都可以帮助解决这个问题,它似乎也没有围绕每个数据库
DECLARE @command NVARCHAR(MAX)
CREATE TABLE #worktable
(
[Database] SYSNAME
,SchemaName SYSNAME
,ObjectName SYSNAME
,StatsName SYSNAME
,ColName SYSNAME
--,Command VARCHAR(500)
)
exec [master].[sys].sp_MSForEachDB @command1="use [?]"
INSERT INTO #worktable
SELECT
'[?]' AS [Database]
,sch.[name] AS [SchemaName]
--,OBJECT_NAME(o.[object_id],DB_ID(''[?]'')) AS [ObjectName]
,o.[Name] AS [ObjectName]
,s.name AS [StatsName]
,c.name AS [ColName]
--,''COMMAND'' AS [Command]
FROM sys.stats AS s
INNER JOIN sys.stats_columns AS sc
ON s.object_id = sc.object_id AND s.stats_id = sc.stats_id
INNER JOIN sys.objects o
INNER JOIN sys.schemas AS sch
ON o.schema_id = sch.schema_id
ON s.[object_id] = o.[object_id]
AND o.is_ms_shipped = 0
INNER JOIN sys.columns AS c
ON sc.object_id = c.object_id AND c.column_id = sc.column_id
select * from #worktable
drop table #worktable
exec [MASTER].[sys].sp_MSForEachDB
INSERT INTO #worktable
SELECT 'Test' AS [Database]
,OBJECT_SCHEMA_NAME(sch.name ,DB_ID(''[?]'')) AS [SchemaName]
,OBJECT_NAME(ss.[object_id],DB_ID(''[?]'')) AS [ObjectName]
,ss.[name] AS [StatsName]
,''UPDATE STATISTICS ''+''[?]''+''.''+OBJECT_SCHEMA_NAME(ss.[object_id],DB_ID(''[?]''))+''.''+OBJECT_NAME(ss.[object_id],DB_ID(''[?]''))+'' ''+ss.[name]+'' WITH FULLSCAN;'' AS Command
FROM [?].sys.stats ss
CROSS APPLY [?].sys.dm_db_stats_properties(ss.[object_id],ss.stats_id) sp
WHERE ( (sp.last_updated < DATEADD(hh,-6,GetDate()))
OR (sp.[modification_counter] > (0.1*sp.[rows]))
OR (sp.[rows_sampled] <> sp.[rows])
)
ORDER BY sp.[rows] ASC -- does the small stuff first, makes the difference earlier'
DECLARE cmdlist CURSOR FOR SELECT Command FROM #worktable
-- Open the cursor.
OPEN cmdlist
-- Loop through the partitions
WHILE (1=1)
BEGIN
FETCH NEXT FROM cmdlist
INTO @command
IF @@FETCH_STATUS < 0 BREAK
--EXEC (@command);
PRINT N'Executed: ' + @command
END;
CLOSE cmdlist
DEALLOCATE cmdlist
DROP TABLE #worktable
GO
Run Code Online (Sandbox Code Playgroud)
我诚实的意见是 - 不要重新发明轮子,因为重新发明它是有成本的。
强烈建议您使用Ola 的索引和统计维护解决方案。
它非常灵活,受到高度评价和测试。此外,它不使用脚本中的任何 ms_foreach 内容。
首先让我说,一般建议您不要使用 sp_msforeachdb。它有一些有据可查的缺陷,偶尔会错过数据库。@AaronBertrand 有一个他写的版本要好得多。
其次,你似乎很早就切断了你的弦。您编写它的方式将像这样执行。
这部分将首先针对每个数据库执行:
exec [master].[sys].sp_MSForEachDB @command1="use [?]"
Run Code Online (Sandbox Code Playgroud)
然后这部分将针对您当前的数据库执行:
INSERT INTO #worktable
SELECT
'[?]' AS [Database]
,sch.[name] AS [SchemaName]
--,OBJECT_NAME(o.[object_id],DB_ID(''[?]'')) AS [ObjectName]
,o.[Name] AS [ObjectName]
,s.name AS [StatsName]
,c.name AS [ColName]
--,''COMMAND'' AS [Command]
FROM sys.stats AS s
INNER JOIN sys.stats_columns AS sc
ON s.object_id = sc.object_id AND s.stats_id = sc.stats_id
INNER JOIN sys.objects o
INNER JOIN sys.schemas AS sch
ON o.schema_id = sch.schema_id
ON s.[object_id] = o.[object_id]
AND o.is_ms_shipped = 0
INNER JOIN sys.columns AS c
ON sc.object_id = c.object_id AND c.column_id = sc.column_id
Run Code Online (Sandbox Code Playgroud)
我的猜测是,您确实希望代码的第一部分如下所示:
DECLARE @sql nvarchar(4000)
SET @SQL = N'use [?];
INSERT INTO #worktable
SELECT
''[?]'' AS [Database]
,sch.[name] AS [SchemaName]
--,OBJECT_NAME(o.[object_id],DB_ID(''[?]'')) AS [ObjectName]
,o.[Name] AS [ObjectName]
,s.name AS [StatsName]
,c.name AS [ColName]
--,''COMMAND'' AS [Command]
FROM sys.stats AS s
INNER JOIN sys.stats_columns AS sc
ON s.object_id = sc.object_id AND s.stats_id = sc.stats_id
INNER JOIN sys.objects o
INNER JOIN sys.schemas AS sch
ON o.schema_id = sch.schema_id
ON s.[object_id] = o.[object_id]
AND o.is_ms_shipped = 0
INNER JOIN sys.columns AS c
ON sc.object_id = c.object_id AND c.column_id = sc.column_id'
exec [master].[sys].sp_MSForEachDB @SQL
Run Code Online (Sandbox Code Playgroud)
您在脚本的后半部分遇到了类似的问题。您想要声明一个变量,将您的命令放入其中,然后针对该变量运行 sp_MSForEachDB。通过这种方式,您可以先打印出您的变量,以确保您正在运行正确的命令。
归档时间: |
|
查看次数: |
408 次 |
最近记录: |