2017-01-19 1 views
1

Ich verwendeKann Java String.format Griff ersetzen? anstelle von% s

db.execSQL("INSERT INTO table SELECT NULL WHERE '1'=?;",new String[]{"1"}); 
db.execSQL("INSERT INTO robot_active_variables\n" + 
        "SELECT NULL, ravs._id,str,val\n" + 
        "FROM (SELECT 'is_answer' AS str, ? AS val\n" + 
        "UNION ALL SELECT 'is_setting', ?\n" + 
        "UNION ALL SELECT 'is_val', ?\n" + 
        "UNION ALL SELECT 'is_group_actions', ?\n" + 
        "UNION ALL SELECT 'is_lone_action', ?\n" + 
        "UNION ALL SELECT '_id', ?\n" + 
        "UNION ALL SELECT 'val', ?) v\n" + 
        "join robot_active_variables_super ravs on ravs._id not in (select _id_parent from robot_active_variables);",new String[]{"1", "0", "0", "0", "0", String.valueOf(idAnswer), "0"}) 

Und ich möchte die SQL-Einsätze zur Ausgabe verwenden log.v.

1 Wie heißt es,% s durch ein String-Array zu ersetzen, und wie lautet der Name für das Ersetzen von "?" mit String-Array? Ich habe diese Strategie sehr oft in c bemerkt, aber nie gewusst, wie es heißt oder wie man es googelt.

2 Kann der Formatierer oder eine andere Methode die obigen Ersetzungen direkt ausführen?

Was ich versucht:

v1: Log.v("custom log.v call " , sql + bindArgs)); 
but i had to copy paste every var into the "?" 

v2: Log.v("custom log.v call " , String.format(sql.replaceAll("\\?","%s"),bindArgs)); 
but then some queries didn't work, it seems that numbers are converted to text, ie: 'select 1=?' with new String[]{"1"} will give false because it becomes 'select 1="1"' 

v3: Log.v("custom log.v call " , String.format(sql.replaceAll("\\?","\"%s\""),bindArgs)); 
works quite well 
+1

Ich weiß nichts von den Java oder Android APIs, die dies tun. Wahrscheinlich müssen Sie Ihren eigenen Such- und Ersetzungsalgorithmus schreiben. Beachten Sie, dass Sie nach dem Suchen und Ersetzen nicht die resultierende Zeichenfolge für die Abfrage verwenden müssen. In der Tat sollten Sie immer noch die ursprüngliche Zeichenfolge mit den '?' S verwenden. –

+1

Warum protokollieren Sie nicht einfach die SQL- und die Value-Arrays, wie sie sind? Z.B. 'sql +" "+ Arrays.toString (bindArgs)'. Auf diese Weise protokollieren Sie, was Sie tatsächlich tun, z. Wenn der Code falsch ist und die Anzahl der Zeichen "?" falsch ist, protokollieren Sie, was Sie tun, anstatt eine andere Ausnahme von der Protokollanweisung zu erhalten, die besagt, dass "% s" nicht übereinstimmt. – Andreas

+0

Nun, ich benutzte sqlliteman, um alles darin zu laufen, weil die Kompilierungszeiten in android Studio aweful sind. Auch alle Db-Fehler im Studio sind schrecklich im Vergleich zur Verwendung eines sqlliteman Fehler (und Sie können auch sehen, welche Tabellen welche Werte enthalten) –

Antwort

1
v2: Log.v("custom log.v call " , String.format(sql.replaceAll("\\?","%s"),bindArgs)); 

aber dann haben einige Abfragen nicht funktioniert, scheint es, dass die Zahlen in Text umgewandelt werden, das heißt: '1 = wählen Sie' mit neuen String [] { "1"} wird falsch geben, weil es

v3: Log.v("custom log.v call " , String.format(sql.replaceAll("\\?","\"%s\""),bindArgs)); 

funktioniert recht gut

Jede dieser Lösungen 'wählen 1 = "1"' wird, ist fein . Beachten Sie, dass Sie in der ersten Version immer noch die ursprüngliche Zeichenfolge verwenden sollten, wenn Sie die Abfrage ausführen, und nicht die formatierte. Wie Sie festgestellt haben, konvertiert die formatierte Version Ihrer Abfrage alle Typen in einen String. Dies ermöglicht der SQL-Engine, die richtigen Typen zu verwenden und die Quotierung zu korrigieren, um eine SQL-Injektion zu vermeiden.

+0

: D Ja, ich bin sowohl db.execSQL und Log.v Befehle ausgeführt und db.execSQL nicht Verwenden Sie den Formatierer, nur Log.v –

Verwandte Themen