Cómo pasar variables dinámicas en una consulta MySQL usando un script de Shell

Cómo pasar variables dinámicas en una consulta MySQL usando un script de Shell

Esta es la parte de mi código:

sample_1=''
sample_1_is_cancelled=''
sample_2=''
sample_2_is_cancelled=''
sample_3=''
sample_3_is_cancelled=''
sample_4=''
sample_4_is_cancelled=''
sample_5=''
sample_5_is_cancelled=''

while read -r insert
do
 eval sample_$i=$(echo $insert| awk -F'|' '{print $1}')
 eval sample_$i_is_cancelled=$(echo $insert| awk -F'|' '{print $2}')
         i=$(( i + 1 ))
         
         done < $logpath/source.txt

mysql -uroot -p -e" insert into ttable(sample_1, sample_1_is_cancelled, sample_2, sample_2_is_cancelled, sample_3, sample_3_is_cancelled, sample_4, sample_4_is_cancelled, sample_5, sample_5_is_cancelled)
                values($sample_1, $sample_1_is_cancelled, $sample_2 $sample_2_is_cancelled, $sample_3, $sample_3_is_cancelled, $sample_4, $sample_4_is_cancelled, $sample_5, $sample_5_is_cancelled);"

Hay un máximo de 5 conjuntos de valores posibles. El mínimo es un juego.

Puedo repetir las variables como a continuación,

eval echo \$sample_$i
eval echo \$sample_${i}_is_cancelled

Pero no puedo pasarlo dentro de la consulta de inserción de la misma manera. Cualquier sugerencia... Por favor ayuda.

Respuesta1

A continuación se muestra un ejemplo de cómo hacer esto usando dos matrices ("campos" y "valores").

#!/bin/bash

declare -a fields values

infile="./source.txt"
#infile="$logpath/source.txt"

i=0
while read -r insert; do
  # split "$insert" into a and b, using | as delimiter
  a="${insert%|*}"
  b="${insert#*|}"

  # create the field names from the loop counter $i
  let i++
  sfield="sample_$i"
  cfield="sample_${i}_is_cancelled"

  fields+=("$sfield" "$cfield")
  values+=("$a" "$b")
done < "$infile"


# show what's in the arrays:
declare -p fields
echo
declare -p values

# now build the SQL string, in parts:

# field names don't need to be quoted
f=$(printf "%s, " "${fields[@]}" | sed -e 's/, $//')

# this assumes values are strings and need to be quoted
v=$(printf "'%s', " "${values[@]}" | sed -e 's/, $//')

sql="$(printf "insert into ttable(%s) values (%s);" "$f" "$v")"

echo
echo "mysql -uroot -p -e \"$sql\""

Dado el siguiente sources.txtarchivo:

$ cat source.txt 
one|two
three|four
foo|bar
junk|more junk

La ejecución del script producirá el siguiente resultado:

declare -a fields=([0]="sample_1" [1]="sample_1_is_cancelled" [2]="sample_2" 
  [3]="sample_2_is_cancelled" [4]="sample_3" [5]="sample_3_is_cancelled"
  [6]="sample_4" [7]="sample_4_is_cancelled")

declare -a values=([0]="one" [1]="two" [2]="three" [3]="four"
  [4]="foo" [5]="bar" [6]="junk" [7]="more junk")

mysql -uroot -p -e "insert into ttable(sample_1, sample_1_is_cancelled, sample_2,
  sample_2_is_cancelled, sample_3, sample_3_is_cancelled,
  sample_4, sample_4_is_cancelled) values ('one', 'two', 'three', 'four',
  'foo', 'bar', 'junk', 'more junk');"

(Se agregaron avances de línea y sangría para mejorar la legibilidad)


NOTA: si necesita hacer más con los nombres de los campos o los valores en el propio script de shell (es decir, más que simplemente usarlo en una instrucción de inserción SQL), entonces probablemente sería mejor usar dos matrices asociativas (una para muestras y uno para muestras canceladas), utilizando las variables $sfield y $cfield como claves para esas matrices. Comencé a escribir el script de esta manera, luego me di cuenta de que era demasiado complicado para la tarea (y habría requerido más trabajo para fusionar los campos y valores para construir la cadena SQL), así que lo simplifiqué para usar solo matrices indexadas $fields y $values. .

información relacionada