SQL personalizzato e valutazione/analisi (e \!\!\!...)CIAO!
Eseguo molte query che non possono utilizzare il generatore di query JMP e devono essere scritte in SQL personalizzato.
Ma poiché voglio anche generalizzare il mio codice, devo integrare molti eval / inserts e \!
Ecco un esempio:
Codice non ancora generalizzato
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;
Codice generalizzato per includere una data:
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?
Su script complessi è davvero difficile da gestire ed eseguire il debug!
Grazie
Accesso ai datiRi: SQL Custom e Eval / Parse (e \!\!\!...)Ottimo, è davvero molto utile! E poiché abbiamo appena creato il database e io sono stato l'attore principale di questa creazione, mi sono appena assicurato che nessun nome di tabella o nome di variabile abbia parentesi o spazi, quindi dovrebbe semplificare questa generalizzazione.
Ri: SQL Custom e Eval / Parse (e \!\!\!...)Mi piace seguire un percorso diverso evitando combinazioni di analisi eval non intuitive, dove le trovo abbastanza utili per altri scopi.
Spesso ho query complesse (costruite in semplice SQL da altri strumenti come lo sviluppatore SQL). E ho bisogno di modificare alcune variabili.
L'esempio allegato Mostra come funziona con datatable di grande classe, tuttavia funzionerebbe per tutte le connessioni ODBC in modo simile.
Semplicemente preparo la mia stringa di connessione (non utilizzata qui) e la query SQL in una variabile stringa, assegnata all'oggetto "Nuova query SQL".
Uso "assign" (invece di "=") perché funziona bene per query di grandi dimensioni e piegatura del codice.
E sono più flessibile anche per l'utilizzo della funzione di database aperto o per l'elaborazione dell'SQL in altri modi.
Di solito le virgolette doppie non sono necessarie in un semplice SQL (e cerco anche di evitarle), a meno che tu non abbia nomi con spazi ecc. Come "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;
Ri: SQL Custom e Eval / Parse (e \!\!\!...)Sono d'accordo che questa sintassi è ovvia solo una volta che la capisci, e anche in questo caso crea confusione.Guardare questo elemento della lista dei desideri per introdurre una funzione Eval Expr First(), forse sarebbe più intuitivo?
Ri: SQL Custom e Eval / Parse (e \!\!\!...)Userei i delimitatori \[ e ]\ per includere le virgolette doppie nella stringa.
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 ) );
Produzione:
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;Ri: SQL Custom e Eval / Parse (e \!\!\!...)Grazie mille! Avevo letto questo articolo e avevo provato, ma ho ancora difficoltà a padroneggiare questo eval (eval expr (expr))
Ri: SQL Custom e Eval / Parse (e \!\!\!...)Ci sono alcune opzioni descritte in Questo articolo , consiglio di iniziare con Eval( Eval Expr()) e quindi avvolgere ogni parte che devi sostituire con Expr() e utilizzare \[ ... ]\ per ridurre il numero di caratteri di escape.Potrebbe assomigliare a questo:
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
) );
Ri: SQL personalizzato e valutazione/analisi (e \!\!\!...)@pmroz Ho provato una cosa simile come sopra. dopo l'esecuzione dell'SQL personalizzato, il risultato restituito è 1 alla fine del log. potresti per favore aiutarmi a spiegare di più sul risultato di 1? è il codice di ritorno Eval( Parse( gbStr ) ) che hai menzionato nel tuo script?

Ri: SQL personalizzato e valutazione/analisi (e \!\!\!...)Mi spiace, non utilizzo Query Builder. Immagino che il valore restituito pari a 1 sia vero, indicando il successo. Ma questa potrebbe essere un’ipotesi folle:)
Ri: SQL personalizzato e valutazione/analisi (e \!\!\!...)@pmroz grazie per la tua risposta. Posso avere il vostro supporto per rivedere il seguente script?
La query SQL richiede in genere alcuni minuti per accedere al database. l'eliminazione di righe (se :rank >1) a volte non viene eseguita ma può essere eseguita manualmente. Non ne ho idea.... non sono sicuro che il mio script abbia qualche problema?
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;
Ri: SQL personalizzato e valutazione/analisi (e \!\!\!...)Penso che la valutazione della formula richieda un po' di tempo,
un wait(0) forzerebbe il completamento di JMP fino al completamento della selezione della riga (vedere script) e dell'eliminazione.
Ti incoraggio davvero a mantenere la parte della stringa il più piccola possibile, poiché è sempre soggetta a errori e difficile da leggere.
Inoltre, è un'ottima possibilità utilizzare le tabelle JMP per risolvere questo tipo di problemi e scrivere script per la comunità che tutti possono eseguire immediatamente.
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;
Ri: SQL personalizzato e valutazione/analisi (e \!\!\!...)@Georg grazie per il suggerimento. è davvero un'idea buona e intelligente mantenere la parte delle corde il più piccola possibile. l'ho provato e la cancellazione continua a fallire con wait(0). ma funziona per wait(1). tuttavia, quando accedo a dati di dimensioni maggiori dal data center SQL (probabilmente sono necessari alcuni minuti per recuperare i dati dal server), funziona fino all'attesa (5). la mia ipotesi è che col rango() di solito richieda del tempo per il calcolo. maggiore dimensione dei dati, più tempo per il calcolo. quando la selezione della riga viene eseguita prima del termine del calcolo del rango delle colonne, l'eliminazione fallirà. c'è un modo per determinare il calcolo completo? se sì, posso utilizzare la funzione SE per eseguire il passaggio successivo.
Ri: SQL personalizzato e valutazione/analisi (e \!\!\!...)@ReliabilityWolf in genere proverei a eseguire il filtraggio nel database, quindi dipende dal linguaggio SQL che hai come eseguire (puoi utilizzare il rango con la sottoselezione anche in SQL). E guadagni molto tempo per il traffico non necessario.
Inoltre eviterei di utilizzare una formula per questo, se vuoi avere valori univoci per l'ID, puoi ordinare in SQL e utilizzare seleziona righe duplicate ed elimina, vedi sotto. Il database di solito è molto più veloce nell'eseguire queste attività rispetto al tuo cliente.
Per quanto riguarda le formule, se necessario, forse il messaggio della tabella "esegui formule" o "riesegui formule" aiuta. Oppure puoi eliminare la formula o scrivere i risultati direttamente nella colonna...
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();
Ri: SQL personalizzato e valutazione/analisi (e \!\!\!...)apprezzo molto la tua nuova direzione sul filtraggio nel database. lasciami dare un'occhiata a questo. grazie ancora.