SQL 自定义和 Eval/解析(和 \!\!\!...)你好!
我做了很多查询,这些查询不能使用 JMP 查询生成器,而必须用 SQL Custom 编写。
但是由于我也想概括我的代码,所以我必须整合很多 eval / 插入和 \!
以下是一个例子:
代码尚未通用
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/解析(和 \!\!\!...)@pmroz我尝试了与上述类似的事情。在自定义 SQL 运行后,在日志末尾返回的结果是 1。您能帮忙解释一下有关 1 的结果的更多信息吗?这是您在脚本中提到的 Eval( Parse( gbStr ) ) 返回代码吗?

回复:SQL 自定义和 Eval/解析(和 \!\!\!...)抱歉,我不使用查询生成器。我猜返回值 1 为真表示成功。但这可能是一个大胆的猜测:)
回复:SQL 自定义和 Eval/解析(和 \!\!\!...)@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/解析(和 \!\!\!...)我认为公式评估需要一些时间,
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/解析(和 \!\!\!...)@Georg感谢您的建议。将字符串部分保持尽可能小确实是一个好主意。我试过了,删除仍然因 wait(0) 而失败。但它适用于 wait(1)。但是,当我从 SQL 数据中心访问更多大小的数据时(可能需要几分钟才能从服务器获取数据),它会一直工作到 wait(5)。我的猜测是 col rank() 通常需要一些时间来计算。数据量越大,计算时间越长。当在 col rank 计算完成之前执行行选择时,删除将失败。有什么办法可以确定计算完成吗?如果是,我可以使用 IF 函数来运行下一步。
回复:SQL 自定义和 Eval/解析(和 \!\!\!...)@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();
回复:SQL 自定义和 Eval/解析(和 \!\!\!...)非常感谢您对数据库过滤的新方向。让我看看这个。再次感谢。