Powershell 嵌套循环中的语法不正确
我有一个powershell脚本来删除过去30天内没有连接的数据库。我将脚本编码如下: $SQLInstances=sql2016、sql2014、sql2012 $SQLQuery=exec usp\U连接计数 $SQLInstances中的foreach$sqLInstance{ 调用Sqlcmd-ServerInstance$sqLInstance-Database master-Query$SQLQuery } 写入输出在过去30天内未使用的任何数据库都将被删除 此处的写入输出是正在监视的SQL实例的列表:$SQLInstances $DBQuery=从[SQLConnections]中选择名称作为数据库名称,其中连接数=0,DATEDIFFday,timestamp,GetDate>30 $DropDb=如果存在,请从master.dbo.sysdatabases中选择名称,其中name='$UnusedDB'删除数据库$UnusedDB $SQLInstances中的foreach$sqLInstance{ $Databases=Invoke Sqlcmd-ServerInstance$sqLInstance-Database master-Query$DBQuery 写入要删除的数据库的输出列表 $Database foreach$UNUSEDB在$Databases中{ 调用Sqlcmd-ServerInstance$sqLInstance-Database master-Query$DropDb } } 我的代码看起来很酷,但当我运行它时,它说 调用Sqlcmd:“数据库”附近的语法不正确 我想不出问题出在哪里。此外,创建SQLConnections表的代码是: 将ANSI_空值设置为ON 去 在上设置带引号的\u标识符 去 创建表[dbo]。[SQLConnections] [server][nvarchar]130不为空, [name][nvarchar]130不为空, [连接数][int]不为空, [时间戳][日期时间]不为空 在[小学] 去 usp_连接计数的代码如下: 将ANSI_空值设置为ON 去 在上设置带引号的\u标识符 去 创建过程usp\U连接计数 像 开始 不计数; 插入[SQLConnections] 选择@ServerName作为服务器 ,名称为dbname ,将状态计数为连接数 ,GETDATE作为时间戳 从sys.sd数据库 左JOIN master.dbo.sysprocesses sd.database_id=sp.dbid上的sp 其中数据库\u id不在1之间 四, 按名称分组 终止Powershell 嵌套循环中的语法不正确,powershell,Powershell,我有一个powershell脚本来删除过去30天内没有连接的数据库。我将脚本编码如下: $SQLInstances=sql2016、sql2014、sql2012 $SQLQuery=exec usp\U连接计数 $SQLInstances中的foreach$sqLInstance{ 调用Sqlcmd-ServerInstance$sqLInstance-Database master-Query$SQLQuery } 写入输出在过去30天内未使用的任何数据库都将被删除 此处的写入输出是正在监视
有人能告诉我错误的语法是从哪里来的吗?我已经看了几个小时了,想不出来?您在以下内容中遇到了字符串引用问题:
$DropDb = "IF EXISTS (SELECT name FROM master.dbo.sysdatabases WHERE name = '$UnusedDB') DROP DATABASE $UnusedDB"
Powershell不会在单个带引号的字符串中替换变量,Powershell不会在其中替换$UnusedDB并将其作为文本保留在字符串中
您可以将其更改为:
$DropDb = "IF EXISTS (SELECT name FROM master.dbo.sysdatabases WHERE name = `"$UnusedDB`") DROP DATABASE $UnusedDB"
你可以找到更多关于引用规则的信息
您还可以尝试通过-f运算符格式化字符串,文档是这样的
希望这能有所帮助。因此,我放弃了让powershell完成大部分工作的想法。我已经设法使用SQL代码来完成大部分工作: $SQLInstances=sql2016、sql2014、sql2012
Write-Output "Any database that has not been used in the last 30 days will be dropped"
Write-Output "Here is a list of SQL Instances being monitored:" $SQLInstances
$DropDb = " --Exec stored procedure to gather information regarding DB connections
EXEC usp_fpmConnectionsCount
IF OBJECT_ID('tempdb..#TempSQLConnections1') IS NOT NULL DROP TABLE #TempSQLConnections
SELECT Distinct(fund.name)
INTO #TempSQLConnections
FROM FundSQLConnections AS fund
INNER JOIN
sys.databases as sdb
on fund.name = sdb.name
WHERE number_of_connections = 0 AND DATEDIFF(day, timestamp, GetDate()) > 30
GO
DECLARE @dbnames nvarchar(max)
DECLARE @statement nvarchar(max)
SET @dbnames = ''
SET @statement = ''
SELECT @dbnames = @dbnames + ',[' + name + ']' from #TempSQLConnections
IF len(@dbnames) = 0
begin
print 'no databases to drop'
end
ELSE
begin
set @statement = 'drop database ' + substring(@dbnames, 2, len(@dbnames))
print @statement
exec sp_executesql @statement
print @dbnames + 'Has been dropped'
end
DROP TABLE #TempSQLConnections "
foreach($sqLInstance in $SQLInstances) {
Invoke-Sqlcmd -ServerInstance $sqLInstance -Database "master" -Query $DropDb
}
像锤子一样工作 我认为这个错误与您的数据库名称有关。看看:。。。删除数据库$UnusedDB。你试过用[]包装$UnusedDB吗?@Marc如果我用[]包装那个变量,它就不起作用了。我得到以下错误:Invoke-Sqlcmd:缺少对象或列名或为空。对于SELECT INTO语句,请验证每个列都有名称。对于其他语句,请查找空别名。不允许定义为或[]的别名。将别名更改为有效名称。