oracle 如何在不使用外部SQL文件的情况下通过Powershell执行SQL查询?

fgw7neuy  于 2023-03-01  发布在  Oracle
关注(0)|答案(4)|浏览(177)

我是一名DBA,我尝试通过PS执行查询,而不是使用SQL Developer登录到每台服务器。但到目前为止,我只成功地使用了外部SQL文件。我尝试使用PS脚本中声明的变量来执行查询。
脚本:

$sqlQuery='GRANT ROLE TO USER;quit;'
$cmd = "cmd.exe"
$srvList = 'SRVONE','SRVTWO','SRVTHREE','SRVFOUR'
echo $srvList
$init = "/c sqlplus user/password//DB_"
$mid = ":1521/"
foreach ($srv in $srvList){
$srvEx +=$init
$srvEx +=$srv
$srvEx +=$mid
$srvEx +=$srv
$srvEx +=" @"
$srvEx +=$sqlQuery
Write-Host $srvEx
&cmd $srvEx;
$srvEx=''
}

上面是我做的脚本,它可以连接到SQL数据库,但是变量$sqlQuery中的查询不会运行,也不会给出任何结果。

4smxwvx5

4smxwvx51#

请使用dba tools。使用Invoke-DbaQuery cmdlet执行此操作非常简单。
我有一个名为vm 4 win10的本地服务器。然而,这将适用于任何版本的SQL服务器,你可以在其中建立连接。下面是我将要使用的变量。

# Set variables
$svr = "vm4win10"
$usr = "jminer"
$dbs = "dbs4advwrks"
$path = "c:\transfer"

获取标准用户“jminer”的密码。如果需要,这可以是Windows用户。

# Credential (standard security)
$crd = (Get-Credential "$usr")

在我的例子中,我将把adventure works的customer表转储到一个csv文件中,但是这个查询很容易成为一个服务器任务。

# extract data
$cust = Invoke-DbaQuery $svr $SqlCredential $crd -Database $dbs -Query 'SELECT * FROM dbs4advwrks.dbo.DimCustomer'

# rec count
$cust.Count

# first record
$cust[0]

显示数据行对象数组的第一个元素。

下一个代码段将$cust变量通过管道传输到一个cmdlet以编写csv文件。

# write file
$cust | Export-Csv -Path "$path\dim-customer.csv" -NoTypeInformation

这显示了我最喜欢的编辑器notepad++中的前几行。

所以,是的,我有点偏离了轨道。但是dba工具有一船的cmdlet给偶然的DBA。
回到你的用例。让我们假设adventure works数据库安装在三台服务器上。用户Robin已经被添加到每台服务器上。现在我们想授予对数据库的控制权限。jminer的凭据对每台服务器都有sysadmin访问权限。

# tsql to execute
$sql = "GRANT CONTROL ON DATABASE::AdventureWorks TO Robin;"

# first server
$svr = "test1svr"
$dbs= "AdventureWorks"
$ret = Invoke-DbaQuery $svr -SqlCredential $crd -Database $dbs -Query $sql

# second server
$svr = "test2svr"
$dbs= "AdventureWorks"
$ret = Invoke-DbaQuery $svr -SqlCredential $crd -Database $dbs -Query $sql

# third server
$svr = "test3svr"
$dbs= "AdventureWorks"
$ret = Invoke-DbaQuery $svr -SqlCredential $crd -Database $dbs -Query $sql

简而言之,使用dbatool很容易。

wgeznvg7

wgeznvg72#

看看这篇文章。它使用ODBC,但应该工作正常。这将需要ORACLE的客户端工具安装在能够访问Oracle服务器的Jump Server上。你甚至可能需要设置你的tnsnames.ora文件。
https://www.andersrodland.com/working-with-odbc-connections-in-powershell/
如果你愿意,第1步可以手工完成。第2步获得DSN连接。第3步执行SQL。如果你不能存储凭据,它可能会提示你输入凭据。这没有DBA工具那么漂亮!

# 1 - Create a DSN (change for oracle)
Add-OdbcDsn -Name "MyPayroll" -DriverName "SQL Server Native Client 10.0" -DsnType "System" -SetPropertyValue @("Server=MyServer", "Trusted_Connection=Yes", "Database=Payroll")

# 2 - Get the DSN
$dsn = Get-OdbcDsn -Name "MyPayroll" -DsnType "System" -Platform "32-bit"

# 3 - Execute non query
$sql = "GRANT CONTROL ON DATABASE::AdventureWorks TO Robin;"
Set-ODBC-Data $sql, $dsn

您必须为要使用的每个服务器设置DSN连接。

dxpyg8gm

dxpyg8gm3#

对于DBA来说,安装Oracle客户端并使用sqlplus来运行SQL和PL/SQL脚本已经是二十多年来的经典做法。使用SQLDeveloper,您可以拥有一个“漂亮”的图形界面来查看查询结果,编辑存储程序单元,并比使用普通sqlplus更容易地查看编译错误。然而,对于运行脚本来说,sqlplus往往是首选。

cfh9epnr

cfh9epnr4#

产出

C:\upwork\sql_run_all_servers>powershell .\run_sql_all_servers.ps1 
SET session NLS_LANG: AMERICAN_AMERICA.UTF8                             
=======================================================
Script start time : 2023-02-28 17:50:06
Script is run on the server : DEV 
-------------------------------------------------------
Script is run on the server : DEV19 
-------------------------------------------------------
Script is run on the server : DEMO19
-------------------------------------------------------
Script stop time : 2023-02-28 17:50:12

脚本

$username = "scott"
$password = "tiger"
$connect_string_list = "DEV","DEV19","DEMO19"
$log_file = "C:\upwork\sql_run_all_servers\log_file.log"

# NLS_NUMERIC_CHARACTERS
$NLS_NUMERIC_CHARACTERS=".,"
$NLS_DATE_FORMAT="DD.MM.YYYY HH24:MI:SS"
# Log file 
$full_log_path=$log_file
#Set NLS_LANG for session sqlplus 
#"AMERICAN_AMERICA.UTF8"
$NLS_LANG="AMERICAN_AMERICA.UTF8"

$PSDefaultParameterValues = @{'Out-File:Encoding' = 'utf8'}

#Set NLS_LANG for session sqlplus 
[Environment]::SetEnvironmentVariable("NLS_LANG",$NLS_LANG , [System.EnvironmentVariableTarget]::PROCESS)
$env_path_NLS=[Environment]::GetEnvironmentVariable("NLS_LANG", [EnvironmentVariableTarget]::PROCESS)

echo "SET session NLS_LANG: $env_path_NLS" | tee-object -Append  -filepath $full_log_path  

$sqlQuery_show_user_tables = 
@"
set heading off
set termout OFF
SET FEEDBACK OFF
SET TAB OFF
set pause off
set verify off
SET UNDERLINE OFF
set trimspool on
set timing off
set echo off
set linesize 10000
set pagesize 0
ALTER SESSION SET NLS_NUMERIC_CHARACTERS='$NLS_NUMERIC_CHARACTERS';
ALTER SESSION SET NLS_DATE_FORMAT='$NLS_DATE_FORMAT'; 
select  TNAME  from tab where tabtype='TABLE' and tname not like 'BIN$%'
;
exit
"@
                         
echo "===========================================================================================" | tee-object -Append  -filepath $full_log_path 

$date_time_start = Get-Date -Format "yyyy-MM-dd HH:mm:ss"            
$date_time_log = Get-Date -Format "yyyyMMddHHmmss"            

Write-host "Script start time : $date_time_start "
try
{
echo "Script start time :  $date_time_start ">>$full_log_path
}
catch {
Write-Host "Log File $full_log_path.  Other type of error was found:"
Write-Host "Exception type is $($_.Exception.GetType().Name)"
exit
}

foreach ($server_alias in $connect_string_list)
{
echo  "Script is run on the server : $server_alias "  | tee-object -Append  -filepath $full_log_path  

$sqlOutput_tab = $sqlQuery_show_user_tables | sqlplus -s $username/$password@$server_alias

Out-File -filepath $full_log_path -append -inputobject $sqlOutput_tab  -Encoding utf8

echo "-------------------------------------------------------------------------------------------"  | tee-object -Append  -filepath $full_log_path  
}
$date_time_stop = Get-Date -Format "yyyy-MM-dd HH:mm:ss"            
echo "Script stop time : $date_time_stop" | tee-object -Append  -filepath $full_log_path

相关问题