SQL 自訂和 Eval/Parse(和 \!\!\!...)你好!
我執行的許多查詢無法使用 JMP 查詢產生器,而必須使用 SQL Custom 編寫。
但因為我也想概括我的程式碼,所以我必須整合大量 eval / insert 和 \!
這是一個例子:
程式碼尚未通用
New SQL Query(
Connection(
"ODBC:blabla"
),
QueryName( "v_test_run" ),
CustomSQL(
"SELECT \!"t1\!".lot_id
FROM \!"public\!".\!"v_test_run\!" \!"t1\!"
WHERE ( ( ( \!"t1\!".test_run_timestamp >= '2020-11-01 15:25:11' ) ) ) ;"
)
) << Modify;
程式碼概括為包含日期:
gbStr = Eval Insert("
New SQL Query(
Connection(
\!"ODBC:blabla\!"
),
QueryName( \!"v_test_run\!" ),
CustomSQL(
\!"SELECT \!\!\!"t1\!\!\!".lot_id
FROM \!\!\!"public\!\!\!".\!\!\!"v_test_run\!\!\!" \!\!\!"t1\!\!\!"
WHERE ( ( ( \!\!\!"t1\!\!\!".test_run_timestamp >= '^date_deb^' ) ) ) ;\!"
)
) << Modify;
");
Eval( Parse( gbStr ) );Is there any other method that would save me from having to juggle with these \!\!\! symbols?
在複雜的腳本上,處理和偵錯真的很困難!
謝謝
資料存取回复:SQL 自定義和評估/解析(和 \!\!\!...)太好了,這真的非常有用! 因為我們剛剛創建了數據庫,而我是這個創建的主要參與者,我只是確保沒有表名或變量名有括號或空格,所以它應該簡化這個概括。
回复:SQL 自定義和評估/解析(和 \!\!\!...)我喜歡走一條不同的道路,避免不直觀的 eval 解析組合,我發現它們對其他目的非常有用。
我經常有復雜的查詢(由 SQL 開發人員等其他工具以普通 SQL 構建)。 我需要修改一些變量。
附加的示例顯示了它如何與大類數據表一起工作,但是它以類似的方式適用於所有 ODBC 連接。
只需準備我的連接字符串(此處未使用)和字符串變量中的 SQL 查詢,將其提供給“New SQL Query”.object。
我使用“賦值”(而不是“=”),因為它適用於大型查詢和代碼折疊。
而且我也更靈活地使用開放數據庫功能,或者以其他方式處理 SQL。
通常在純 SQL 中不需要雙引號(我也盡量避免),除非您的名稱帶有空格等,例如“Big Class”。
Names Default To Here( 1 );
cdt = Open( "$Sample_Data\Big Class.jmp" );
age = "15";
// define custom SQL with placeholder
Assign( sql_str, "SELECT t1.name, t1.age, t1.sex, t1.height,
t1.weight
FROM \!"Big Class\!" t1
WHERE ( ( ( t1.age IN ( &age ) ) ) ) ;" );
// fill placeholder
Substitute Into( sql_str, "&age", "15" );
// execute query
dt_age = New SQL Query( Version( 130 ), Connection( "JMP" ), JMP Tables( cdt ), QueryName( "aged" || "_" || age ), CustomSQL( sql_str ) ) << Run;
回复:SQL 自定義和評估/解析(和 \!\!\!...)我同意這種語法只有在您理解它之後才顯而易見,即使那樣它也會令人困惑。查看這個願望清單項目引入一個 Eval Expr First() 函數,也許這樣會更直觀?
回复:SQL 自定義和評估/解析(和 \!\!\!...)我會使用分隔符 \[ 和 ]\ 在字符串中包含雙引號。
date_deb = "to_date('01-Mar-2019', 'dd-mon-yyyy')";
gbStr = Eval Insert("\[
New SQL Query(
Connection(
"ODBC:blabla"
),
QueryName( "v_test_run" ),
CustomSQL(
"SELECT "t1".lot_id
FROM "public"."v_test_run" "t1"
WHERE ( ( ( "t1".test_run_timestamp >= ^date_deb^ ) ) ) ;"
)
) << Modify;
]\");
write(gbstr);
Eval( Parse( gbStr ) );
輸出:
New SQL Query(
Connection(
"ODBC:blabla"
),
QueryName( "v_test_run" ),
CustomSQL(
"SELECT "t1".lot_id
FROM "public"."v_test_run" "t1"
WHERE ( ( ( "t1".test_run_timestamp >= to_date('01-Mar-2019', 'dd-mon-yyyy') ) ) ) ;"
)
) << Modify;回复:SQL 自定義和評估/解析(和 \!\!\!...)非常感謝! 我讀過這篇文章並嘗試過,但我仍然很難掌握這個 eval (eval expr (expr))
回复:SQL 自定義和評估/解析(和 \!\!\!...)中列出了幾個選項本文,我建議從 Eval( Eval Expr()) 開始,然後用 Expr() 包裝你需要替換的每一部分,並使用 \[ ... ]\ 來減少轉義字符的數量。它可能看起來像這樣:
Eval( Eval Expr(
New SQL Query(
Connection(
"ODBC:blabla"
),
QueryName( "v_test_run" ),
CustomSQL(
Expr( "\[SELECT "t1".lot_id
FROM "public"."v_test_run" "t1"
WHERE ( ( ( "t1".test_run_timestamp >= ']\" || date_deb || "' ) ) ) ;")
)
) << Modify
) );
回覆:SQL 自訂和 Eval / Parse(和 \!\!\!...)@pmroz我嘗試了與上面類似的事情。自訂SQL運行後,日誌末尾回傳結果為1。您能幫忙解釋一下 1 的結果嗎?您在腳本中提到的是 Eval( Parse( gbStr ) ) 回傳程式碼嗎?

回覆:SQL 自訂和 Eval / Parse(和 \!\!\!...)抱歉,我不使用查詢產生器。我猜想回傳值1是true表示成功。但這可能是個瘋狂的猜測:)
回覆:SQL 自訂和 Eval / Parse(和 \!\!\!...)@pmroz感謝您的回覆。您可以幫我審查以下腳本嗎?
SQL 查詢通常需要幾分鐘才能存取資料庫。刪除行(如果:rank > 1)有時不會執行,但可以手動執行。我不知道...不確定我的腳本是否有問題?
date_deb = "to_date('01-Mar-2019', 'dd-mon-yyyy')";
gbStr = Eval Insert("\[
dt1 = New SQL Query(
Connection(
"ODBC:blabla"
),
QueryName( "v_test_run" ),
CustomSQL(
"SELECT "t1".lot_id
FROM "public"."v_test_run" "t1"
WHERE ( ( ( "t1".test_run_timestamp >= ^date_deb^ ) ) ) ;"
)
) << Run foreground;
]\");
write(gbstr);
Eval( Parse( gbStr ) );
dt1 << New Column( "Rank", Numeric, "Continuous", Format( "Best", 12 ) );
dt1:Rank << set Formula( Col Rank( :DATE* -1, :ID ) );
dt1 << Row Selection(select where(:Rank > 1 ));
dt1 << delete rows;
回覆:SQL 自訂和 Eval / Parse(和 \!\!\!...)我認為公式評估需要一些時間,
wait(0) 將強制 JMP 完成,直到完成行選擇(請參閱腳本)並且可以完成刪除。
我真的鼓勵您使字串部分盡可能小,因為它總是容易出錯且難以閱讀。
此外,使用 JMP 表來解決此類問題並為社區編寫每個人都可以開箱即用的腳本也是一個很好的可能性。
Edited: replaced "\C:\Program Files\JMP\JMPPRO\18\Samples\Data" by "$SAMPLE_DATA"
Names Default To Here( 1 );
// date_deb = "to_date('01-Mar-2019', 'dd-mon-yyyy')";
date_str = "2008-06-19";
/*
gbStr = Eval Insert("\[
dt1 = New SQL Query(
Connection(
"ODBC:blabla"
),
QueryName( "v_test_run" ),
CustomSQL(
"SELECT "t1".lot_id
FROM "public"."v_test_run" "t1"
WHERE ( ( ( "t1".test_run_timestamp >= ^date_deb^ ) ) ) ;"
)
) << Run foreground;
]\");
*/
dt1_sql = Eval Insert(
"\[SELECT t1.Date, t1.State, t1."Flu Cases", t1.Region,
t1."Population (July 2009)"
FROM "Seasonal Flu" t1
WHERE ( ( ( t1.Date >= JMPDATE('^date_str^') ) ) ) ;]\"
);
dt1 = New SQL Query(
Version( 130 ),
Connection( "JMP" ),
JMP Tables( ["Seasonal Flu" => "$SAMPLE_DATA\Seasonal Flu.jmp"] ),
QueryName( "SQLQuery1" ),
CustomSQL( dt1_sql )
) << run;
// Write( gbstr );
// Eval( Parse( gbStr ) );
dt1 << New Column( "Rank", Numeric, "Continuous", Format( "Best", 12 ) );
dt1:Rank << set Formula( Col Rank( :DATE * -1, /* :ID */ :State) );
wait(0);
dt1 << Row Selection( select where( :Rank > 1 ) );
dt1 << delete rows;
回覆:SQL 自訂和 Eval / Parse(和 \!\!\!...)@Georg感謝您的建議。這確實是一個讓弦樂部分盡可能小的好主意。我嘗試了一下,刪除仍然失敗並等待(0)。但它適用於 wait(1)。但是,當我從 SQL 資料中心存取更多大小的資料時(可能需要幾分鐘才能從伺服器取得資料),它會一直工作到 wait(5)。我的猜測是 colrank() 通常需要一些時間來計算。資料量越大,計算時間越長。當在列排名計算完成之前執行行選擇時,刪除將會失敗。有什麼方法可以判斷計算完成嗎?如果是,我可以使用 IF 函數運行下一步。
回覆:SQL 自訂和 Eval / Parse(和 \!\!\!...)@ReliabilityWolf通常我會嘗試在資料庫中進行過濾,所以這取決於您所使用的sql語言(您也可以在sql中使用帶有子選擇的rank)。而且您將為不必要的交通贏得大量時間。
另外,我會避免為此使用公式,如果您想要 ID 具有唯一值,您可以在 SQL 中排序並使用選擇重複行並刪除,請參見下文。資料庫執行這些任務的速度通常比客戶端快得多。
關於公式,如果您需要,也許表訊息「運行公式」或「重新運行公式」會有所幫助。或者你可以刪除公式,或是將結果直接寫入列...
Names Default To Here( 1 );
date_str = "2008-06-19";
dt1_sql = Eval Insert(
"\[SELECT t1.Date, t1.State, t1."Flu Cases", t1.Region,
t1."Population (July 2009)"
FROM "Seasonal Flu" t1
WHERE ( ( ( t1.Date >= JMPDATE('^date_str^') ) ) )
order by
t1.State, t1.date desc;]\"
);
dt1 = New SQL Query(
Version( 130 ),
Connection( "JMP" ),
JMP Tables( ["Seasonal Flu" => "$SAMPLE_DATA\Seasonal Flu.jmp"] ),
QueryName( "SQLQuery1" ),
CustomSQL( dt1_sql )
) << run;
dt1 << Select Duplicate Rows( Match( :State ) ) << delete rows();
回覆:SQL 自訂和 Eval / Parse(和 \!\!\!...)非常感謝您在資料庫過濾方面的新方向。讓我看一下這個。再次感謝。