SQL Custom et Eval / Parse (et \!\!\!...)Salut!
Je fais beaucoup de requêtes qui ne peuvent pas utiliser le générateur de requêtes JMP et doivent être écrites en SQL Custom.
Mais comme je souhaite aussi généraliser mon code je dois intégrer beaucoup d'eval/inserts et de \!
Voici un exemple:
Code pas encore généralisé
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;
Code généralisé pour inclure une date :
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?
Sur des scripts complexes, c'est vraiment difficile à gérer et à déboguer !
Merci
Accès aux donnéesRe : SQL personnalisé et Eval / Parse (et \!\!\!...)Super, c'est vraiment très utile ! Et puisque nous venons de créer la base de données et que j'étais l'acteur principal de cette création, je me suis juste assuré qu'aucun nom de table ou nom de variable n'ait de parenthèses ou d'espaces, cela devrait donc simplifier cette généralisation.
Re : SQL personnalisé et Eval / Parse (et \!\!\!...)J'aime suivre un chemin différent en évitant les combinaisons d'analyse eval non intuitives, où je les trouve très utiles à d'autres fins.
J'ai souvent des requêtes complexes (construites en SQL brut par d'autres outils comme le développeur SQL). Et j'ai besoin de modifier certaines variables.
L'exemple ci-joint montre comment cela fonctionne avec une grande table de données de classe, comment cela fonctionnerait pour toutes les connexions ODBC de la même manière.
Je prépare simplement ma chaîne de connexion (non utilisée ici) et la requête SQL dans une variable de chaîne, donnée à l'objet "Nouvelle requête SQL".
J'utilise "assign" (au lieu de "=") car cela fonctionne bien pour les grandes requêtes et le pliage de code.
Et je suis plus flexible pour utiliser également la fonction de base de données ouverte ou pour traiter le SQL d'une autre manière.
Habituellement, les guillemets doubles ne sont pas nécessaires dans un SQL simple (et j'essaie également d'éviter), sauf si vous avez des noms avec des espaces, etc. comme "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;
Re : SQL personnalisé et Eval / Parse (et \!\!\!...)Je suis d'accord que cette syntaxe n'est évidente qu'une fois que vous la comprenez, et même alors, elle est déroutante.Vérifier cet élément de la liste de souhaits pour introduire une fonction Eval Expr First(), peut-être que ce serait plus intuitif ?
Re : SQL personnalisé et Eval / Parse (et \!\!\!...)J'utiliserais les délimiteurs \[ et ]\ pour inclure des guillemets doubles dans la chaîne.
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 ) );
Sortir:
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 personnalisé et Eval / Parse (et \!\!\!...)Merci beaucoup! J'avais lu cet article et avais essayé mais j'ai encore des difficultés à maîtriser cet eval (eval expr (expr))
Re : SQL personnalisé et Eval / Parse (et \!\!\!...)Il y a quelques options décrites dans Cet article , je recommande de commencer par Eval( Eval Expr()), puis d'envelopper chaque élément que vous devez remplacer par Expr(), et d'utiliser \[ ... ]\ pour réduire le nombre de caractères échappés.Cela pourrait ressembler à ceci :
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 Custom et Eval/Parse (et \!\!\!...)@pmroz J'ai essayé la même chose que ci-dessus. après l'exécution de SQL personnalisé, le résultat renvoyé est 1 à la fin du journal. pourriez-vous s'il vous plaît aider à expliquer davantage le résultat de 1 ? est-ce le code de retour Eval( Parse( gbStr ) ) que vous avez mentionné dans votre script ?

Re : SQL Custom et Eval/Parse (et \!\!\!...)Désolé, je n'utilise pas Query Builder. Je suppose que la valeur de retour de 1 est vraie, indiquant le succès. Mais cela pourrait être une hypothèse folle:)
Re : SQL Custom et Eval/Parse (et \!\!\!...)@pmroz merci pour votre réponse. Puis-je avoir votre soutien pour réviser le script suivant ?
La requête SQL prend généralement quelques minutes pour accéder à la base de données. la suppression de lignes (si :rank >1) ne s'exécute parfois pas mais peut le faire manuellement. Je n'en ai aucune idée... vous ne savez pas si mon script a un problème ?
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 Custom et Eval/Parse (et \!\!\!...)Je pense que l'évaluation des formules prend du temps,
un wait(0) forcerait JMP à terminer jusqu'à ce que la sélection de ligne soit terminée (voir script) et que la suppression puisse être effectuée.
Je vous encourage vraiment à garder la partie chaîne aussi petite que possible, car elle est toujours sujette aux erreurs et difficile à lire.
De plus, c'est une excellente possibilité d'utiliser les tables JMP pour résoudre ce genre de problèmes et d'écrire des scripts pour la communauté que tout le monde peut exécuter immédiatement.
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 Custom et Eval/Parse (et \!\!\!...)@Georg merci pour la suggestion. c'est vraiment une bonne et intelligente idée de garder la partie corde aussi petite que possible. je l'ai essayé et la suppression échoue toujours avec wait(0). mais ça marche pour wait(1). cependant, lorsque j'accède à des données de plus grande taille à partir du centre de données SQL (il faudra probablement quelques minutes pour récupérer les données du serveur), cela fonctionne jusqu'à attendre (5). je suppose que col Rank() prend généralement un certain temps à calculer. plus de taille de données, plus de temps pour le calcul. lorsque la sélection de ligne est exécutée avant la fin du calcul du classement des colonnes, la suppression échouera. existe-t-il un moyen de déterminer si le calcul est terminé ? si oui, je peux utiliser la fonction IF pour exécuter l'étape suivante.
Re : SQL Custom et Eval/Parse (et \!\!\!...)@ReliabilityWolf en général, j'essaierais de filtrer la base de données, cela dépend donc du langage SQL que vous utilisez (vous pouvez également utiliser le classement avec sous-sélection dans SQL). Et vous gagnez beaucoup de temps pour un trafic inutile.
De plus, j'éviterais d'utiliser une formule pour cela, si vous souhaitez avoir des valeurs uniques pour l'ID, vous pouvez trier en SQL et utiliser la sélection des lignes en double et la suppression, voir ci-dessous. La base de données est généralement beaucoup plus rapide pour effectuer ces tâches que votre client.
Concernant les formules, si vous en avez besoin, le message du tableau « exécuter les formules » ou « réexécuter les formules » peut vous aider. Ou vous pouvez supprimer la formule, ou écrire les résultats directement dans la colonne...
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 Custom et Eval/Parse (et \!\!\!...)j'apprécie vraiment votre nouvelle direction sur le filtrage dans la base de données. laissez-moi jeter un œil à cela. Merci encore.