SQL カスタムおよび評価/解析 (および \!\!\!...)こんにちは!
JMP クエリ ビルダーを使用できず、SQL カスタムで記述する必要があるクエリを多数実行します。
しかし、コードを一般化したいので、多くの eval / inserts と \! を統合する必要があります。
次に例を示します。
コードはまだ一般化されていない
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?
複雑なスクリプトでは、処理とデバッグが非常に困難になります。
ありがとう
データアクセスRe: SQL Custom と Eval / Parse (および \!\!\!...)すごい、それは本当にとても便利です! データベースを作成したばかりで、私がこの作成の主役だったので、テーブル名または変数名に括弧やスペースが含まれていないことを確認しただけなので、この一般化を簡素化する必要があります.
Re: SQL Custom と Eval / Parse (および \!\!\!...)私は直感的ではない eval 解析の組み合わせを避けて別の道をたどるのが好きです。そこでは、それらが他の目的に非常に役立つことがわかりました。
多くの場合、複雑なクエリがあります (SQL 開発者などの他のツールによってプレーン SQL に組み込まれています)。 そして、いくつかの変数を変更する必要があります。
添付の例は、大きなクラスのデータテーブルでどのように機能するかを示していますが、同様の方法ですべての ODBC 接続で機能します。
単純に、接続文字列 (ここでは使用しません) と SQL クエリを文字列変数で準備し、"New SQL Query".object に指定します。
大規模なクエリとコードの折りたたみに適しているため、(「=」の代わりに) 「割り当て」を使用します。
また、オープン データベース機能を使用したり、他の方法で SQL を処理したりする場合にも、より柔軟に対応できます。
「Big Class」のようにスペースなどを含む名前がない限り、通常、プレーン SQL では二重引用符は必要ありません (私も避けようとしています)。
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;
Re: SQL Custom と Eval / Parse (および \!\!\!...)この構文は、理解して初めて明らかであり、それでも混乱を招くことに同意します。チェックアウトこのウィッシュリスト項目Eval Expr First() 関数を導入するには、おそらくそれがより直感的でしょうか?
Re: SQL Custom と Eval / Parse (および \!\!\!...)文字列に二重引用符を含めるには、区切り文字 \[ および ]\ を使用します。
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;Re: SQL Custom と Eval / Parse (および \!\!\!...)どうもありがとうございます! この記事を読んで試してみましたが、まだこの eval (eval expr (expr)) をマスターするのに苦労しています。
Re: SQL Custom と Eval / Parse (および \!\!\!...)で概説されているいくつかのオプションがあります。この記事、 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
) );
Re: SQL カスタムと Eval/Parse (および \!\!\!...)@pmroz上記と同様のことを試しました。カスタム SQL を実行した後、ログの最後に結果 1 が返されます。1 の結果について詳しく説明していただけますか? スクリプトで言及した Eval( Parse( gbStr ) ) の戻りコードですか?

Re: SQL カスタムと Eval/Parse (および \!\!\!...)申し訳ありませんが、私はクエリビルダーを使用していません。戻り値 1 は成功を示す true だと思います。しかし、それは推測が大雑把すぎるかもしれません。:)
Re: 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;
Re: 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;
Re: SQL カスタムと Eval/Parse (および \!\!\!...)@Georg提案ありがとうございます。文字列部分をできるだけ小さく保つための、本当に良い賢いアイデアです。試してみましたが、wait(0) では削除が失敗します。しかし、wait(1) では機能します。ただし、SQL データセンターからよりサイズの大きいデータにアクセスすると (サーバーからデータを取得するのに数分かかる可能性があります)、wait(5) まで機能します。私の推測では、col rank() の計算には通常、ある程度の時間がかかります。データ サイズが大きいほど、計算に時間がかかります。col rank の計算が完了する前に行選択を実行すると、削除は失敗します。計算が完了したことを確認する方法はありますか? あれば、IF 関数を使用して次の手順を実行できます。
Re: SQL カスタムと Eval/Parse (および \!\!\!...)@ReliabilityWolf一般的には、データベースでフィルタリングを試みます。そのため、実行方法は、使用している SQL 言語によって異なります (SQL では、サブセレクトでランクを使用することもできます)。また、不要なトラフィックに多くの時間を費やすことになります。
さらに、このために数式を使用することは避けてください。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();
Re: SQL カスタムと Eval/Parse (および \!\!\!...)データベースでのフィルタリングに関する新しい方向性に本当に感謝しています。これを見てみます。改めて感謝します。