ニッチすぎる。
ODBCとかOracleClientとかそっち使えよって感じだけど
業務上PowerShell+SQLPLusじゃないとダメって人向け。
Hoge.ps1
# チェック
if(!$ENV:Path.Contains("C:\Oracle\bin")){
$ENV:Path+=";C:\Oracle\bin"
echo "ADD PATH"
}
# SQL*Plusを使用してSQLファイルを実行し、結果を受け取る
$sqlPlusOutput = @"
set heading on
set underline off
set termout off
set feedback off
set colsep ,
set lines 9999
set trimspool on
set trimout on
set tab off
SET RECSEP OFF
select * from TABLE1 WHERE COLUMN1 in ('11','21');
"@
$command = @"
echo '$sqlPlusOutput' | sqlplus -S -L 'sys/Oradoc_db1@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(Host=localhost)(Port=1521))(CONNECT_DATA=(SID=ORCLCDB)))' as sysdba
"@
$table = (Invoke-Expression -Command $command)
if($table | Out-String -Stream | ?{$_.Contains('ORA-') -or $_.Contains('SP2-')}) {
echo $table
exit 1
}
$data = @()
$Header = @()
foreach($row in $table[1].Split(",")){
$Header += $row.Trim()
}
for ($i = 2; $i -lt $table.Length; $i++) {
$rowData = @{}
for ($j = 0; $j -lt $Header.Length; $j++) {
$columnName = $Header[$j]
$rowData[$columnName] = ($table[$i].Split(","))[$j].Trim()
}
$data += $rowData
}
echo $data[1].COLUMN4
batcher.bat
@echo off
REM 引数チェック
if "%~1"=="" (
echo Usage: executeBat.bat 100
exit 11
)
SET script_path=C:\IF\powershell.ps1
if not exist "%script_path%" (
echo スクリプトが見つかりません: %script_path%
exit 1
)
powershell -ExecutionPolicy Bypass -File "%script_path%" %~1
set powershell_exit_code=%errorlevel%
if %powershell_exit_code% equ 0 (
echo PowerShell スクリプトは正常に終了しました。 管理番号[%~1]
) else (
echo PowerShell スクリプトはエラーで終了しました。管理番号[%~1] エラーコード: %powershell_exit_code%
)
exit %powershell_exit_code%
exec.sql
DECLARE
v_table_name VARCHAR2(100) := '&table_name';-- テーブル名をパラメータとして指定
v_execute_sql VARCHAR(200); -- 実行するSQLを格納
v_cursor PLS_INTEGER; -- カーソルを定義
v_column_count INTEGER; -- 列数を格納する変数
v_column_desc dbms_sql.desc_tab; -- 列の情報を格納する配列
v_column_name VARCHAR2(100); -- 列名を格納する変数
v_column_value VARCHAR2(4000); -- 列の値を格納する変数、適宜サイズを調整
v_pre_count VARCHAR2(100); -- pre件数を取得する
v_pre_sql VARCHAR2(200); -- pre実行するSQLを格納
BEGIN
-- カーソルを開く
v_cursor := dbms_sql.open_cursor;
-- SQLの準備
v_execute_sql := 'SELECT * FROM ' || v_table_name;
v_pre_sql := 'SELECT count(*) FROM ' || v_table_name;
-- SQL文を解析する
dbms_sql.parse(v_cursor, v_execute_sql, dbms_sql.native);
-- 列の情報を取得する
dbms_sql.describe_columns(v_cursor, v_column_count, v_column_desc);
-- 行数と、列数を出力する
EXECUTE IMMEDIATE v_pre_sql into v_pre_count;
DBMS_OUTPUT.PUT_LINE(v_pre_count||','||v_column_count);
-- 各列について処理を行う
FOR i IN 1..v_column_count LOOP
-- 列名を取得
v_column_name := v_column_desc(i).col_name;
-- 列の値を定義
dbms_sql.define_column(v_cursor, i, v_column_value, 4000);
END LOOP;
-- 実行結果をバインドする
dbms_sql.define_column(v_cursor, 1, v_column_value, 4000);
-- SQL文を実行する
IF dbms_sql.execute(v_cursor) = 0 THEN
-- 結果を取得する
LOOP
EXIT WHEN dbms_sql.fetch_rows(v_cursor) = 0;
FOR i IN 1..v_column_count LOOP
-- 列の値を取得
dbms_sql.column_value(v_cursor, i, v_column_value);
-- 結果を出力
DBMS_OUTPUT.PUT_LINE(v_column_desc(i).col_name || ',' || v_column_value);
END LOOP;
END LOOP;
END IF;
-- カーソルを閉じる
dbms_sql.close_cursor(v_cursor);
END;
/
psooo.ps1
Set-StrictMode -Version 3.0
$BATCH_RESULT = [ordered]@{
SUCC = 0; # 成功
ERR = -1; # エラー
}
$PLSQL_RESULT = [ordered]@{
SUCC = 0; # 成功
ERR = 1; # エラー
PERR = 2; # 一部エラー
WARN = 3; # 警告
}
$EXE_STATE = [ordered]@{
RUN = 0; # 実行中
WAIT = 1; # 待機中
}
$resultValue = $PLSQL_RESULT.ERR;
Write-Host $($PLSQL_RESULT.WARN)
if($resultValue -eq $PLSQL_RESULT.ERR) {
Write-Host "result_VAlue is err"
}
$key = ($EXE_STATE.GetEnumerator() | Where-Object { $_.Value -eq $resultValue }).Key
Write-Host $key
$($BATCH_RESULT | Out-String -Stream | %{ $_ -replace "\s+$" ,''} )
$($PLSQL_RESULT | Out-String -Stream | %{ $_ -replace "\s+$" ,''} )
solo.ps1
# 関数の呼び出しを別プロセスとして実行
$to = "recipient@example.com"
$from = "sender@example.com"
$subject = "Test Email"
$body = "This is a test email sent from PowerShell."
$smtpServer = "smtp.example.com"
$port = 587
$username = "your_smtp_username"
$password = "your_smtp_password"
$job = Start-Job -ScriptBlock {
param (
$To, $From, $Subject, $Body, $SmtpServer, $Port, $Username, $Password
)
# 関数の再定義
function Send-Email {
param (
[string]$To,
[string]$From,
[string]$Subject,
[string]$Body,
[string]$SmtpServer,
[int]$Port = 25,
[string]$Username,
[string]$Password
)
try {
# Send-MailMessage コマンドレットを使用してメールを送信
Send-MailMessage -To $To -From $From -Subject $Subject -Body $Body -SmtpServer $SmtpServer -Port $Port -ErrorAction Stop
# 正常終了の場合の終了コード
return 0
}
catch {
# エラーメッセージを表示
Write-Error "Errorです.$PID $_"
# 異常終了の場合の終了コード
return 1
}
}
# 関数の呼び出し
Send-Email -To $To -From $From -Subject $Subject -Body $Body -SmtpServer $SmtpServer -Port $Port -Username $Username -Password $Password
} -ArgumentList $to, $from, $subject, $body, $smtpServer, $port, $username, $password
try {
# ジョブの終了を待機して結果を表示
$job | Wait-Job >> $null
# 終了コードを取得
$jobResult = $job | Receive-Job
if ($jobResult -eq 0) {
Write-Output "メール送信が正常に完了しました。"
} else {
Write-Output "メール送信中にエラーが発生しました。"
}
}catch {
Write-Host "$PID OK__ $_ "
} finally {
# ジョブの削除
Remove-Job -Job $job
}
debugcursor.sql
DECLARE
TYPE ref_cursor IS REF CURSOR;
c ref_cursor;
l_sql VARCHAR2(32767) := 'SELECT empno, ename, job, mgr, hiredate, sal, comm, deptno FROM emp'; -- 可変SQL
l_column_value VARCHAR2(4000);
l_column_name VARCHAR2(4000);
l_column_list DBMS_SQL.desc_tab2;
l_cursor INTEGER;
l_dummy INTEGER;
PROCEDURE debug_dynamic_cursor(p_cursor IN ref_cursor) IS
l_col_cnt INTEGER;
l_desc DBMS_SQL.desc_tab2;
l_col_name VARCHAR2(1000);
l_col_type NUMBER;
l_rowid ROWID;
l_value VARCHAR2(4000);
BEGIN
l_cursor := DBMS_SQL.TO_CURSOR_NUMBER(p_cursor);
DBMS_SQL.describe_columns2(l_cursor, l_col_cnt, l_desc);
FOR i IN 1 .. l_col_cnt LOOP
l_col_name := l_desc(i).col_name;
l_col_type := l_desc(i).col_type;
DBMS_SQL.DEFINE_COLUMN(l_cursor, i, l_value, 4000);
CASE l_col_type
WHEN 1 THEN
DBMS_SQL.DEFINE_COLUMN(l_cursor, i, l_value, 4000); -- VARCHAR2
WHEN 2 THEN
DBMS_SQL.DEFINE_COLUMN(l_cursor, i, l_value, 4000); -- NUMBER
WHEN 12 THEN
DBMS_SQL.DEFINE_COLUMN(l_cursor, i, l_value, 4000); -- DATE
ELSE
DBMS_SQL.DEFINE_COLUMN(l_cursor, i, l_value, 4000); -- その他の型
END CASE;
END LOOP;
IF DBMS_SQL.FETCH_ROWS(l_cursor) > 0 THEN
FOR i IN 1 .. l_col_cnt LOOP
DBMS_SQL.COLUMN_VALUE(l_cursor, i, l_value);
DBMS_OUTPUT.PUT_LINE(l_desc(i).col_name || ': ' || l_value);
END LOOP;
END IF;
DBMS_SQL.CLOSE_CURSOR(l_cursor);
END debug_dynamic_cursor;
BEGIN
-- 動的SQLを開く
OPEN c FOR l_sql;
-- デバッグ用プロシージャを呼び出し
debug_dynamic_cursor(c);
-- カーソルを閉じる
CLOSE c;
END;
/