Bash script mysql insert into on duplicate key update visszatérési érték

Sziasztok!

Szeretném a segítségeteket kérni! Adott az alábbi függvény egy bash scriptből:

function mysql_insert_or_update()
{
local ip=$1
local stat=1
mysql << EOF
INSERT INTO firewall.kontener (ip) VALUES (INET_ATON('$ip')) ON DUPLICATE KEY UPDATE ts=(NOW());
EOF
stat=$?
return $stat
}

mysql_insert_or_update $IP

Az lenne a kérdésem, hogy szerintetek az megoldható valahogy, hogy visszakapja a függvényből, hogy insert-ált vagy update-elt?

Vagy muszály lesz ketté szednem? PL.:

function mysql_insert()
{
local ip=$1
local stat=1
mysql << EOF
INSERT INTO firewall.kontener (ip) VALUES (INET_ATON('$ip'));
EOF
stat=$?
return $stat
}

function mysql_update()
{
local ip=$1
local stat=1
mysql << EOF
INSERT INTO firewall.kontener (ip) VALUES (INET_ATON('$ip')) ON DUPLICATE KEY UPDATE ts=(NOW());
EOF
stat=$?
return $stat
}

mysql_insert $IP || mysql_update $IP

Logolnom kell, hogy a script insert-ált vagy update-elt?
Felesleges mysql műveletet nem szeretnék végeztetni.

Előfordulhat, hogy rossz irányból közelítem meg a problémát!
Segítségeteket előre is köszönöm!

Hozzászólások

Az adatbázisos részbe nincs kedvem beleélni magam. Ha a kérdésed az, hogyan lehet több paramétert visszaadni shell függvényből, arra az a megfejtés, hogy az stdout-ra írsz valamilyen delimiterrel, a hívó helyen pedig szétbontod ezt:

function fgv() {
echo "elso,masodik,harmadik"
}

retval=`fgv`

ret1=`cut -d, -f1 <<<"$retval"`
ret2=`cut -d, -f2 <<<"$retval"`
ret3=`cut -d, -f3 <<<"$retval"`

Arra kell figyelni, hogy senki más ne írjon a függvényen belül stdout-ra. Azt vagy a /dev/null-ba, vagy stderr-re kell irányítani.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Nem ertem a problemadat, azt mondod sql-nek hogy insertalja be azt az adatot, de teged nem erdekel ha mar van ilyen csak tegye be (vagyis meglevot cserelje le az ujra). Aztan megis azt varod tole hogy megmondja volt-e mar ilyen?

Ha valoban szukseged van ra, hogy van-e mar olyan akkor kerdezd le elotte es ha nem akkor mondj insertet, vagy ne tedd meg unique-nak azt az erteket, hanem mas adatbazis logikat tegyel bele.

Azt ne felejtsd el, hogy ha select-tel lekérdezed, és ettől függően insertelsz, update-elsz, akkor az már nem atomi művelet. Nyilván ez nem fontos, ha garantált, hogy a script több példánya nem fut párhuzamosan.

A problémád amúgy az on duplicate key update formával is megoldható lett volna az affected rows értékének a figyelésével. Ha új sort szúr be a query, akkor az affected rows 1, egyébként meg nem (valószínűleg 2, vagy 0).

Köszön a segítséget! Pont erre volt szükségem. A script több példányban is fog futni.

Én elsőre egy ilyen megoldást gondoltam:

function mysql_insert_or_update()
{
local ip=$1
local stat=1
mysql --skip-column-names << EOF
INSERT INTO firewall.kontener (ip) VALUES (INET_ATON('$ip')) ON DUPLICATE KEY UPDATE ts=(NOW());
SELECT ROW_COUNT();
EOF
stat=$?
return $stat
}

if [ "$(mysql_insert_or_update $IP)" == "1" ]; then
echo "Bekerült az adatbázisba!"
else
echo "Timestamp frissítve!"
fi

OK. Verbose módban futtattam a mysql klienst és a kimenetére greppeltem majd ezt feletettem meg.


function mysql_insert_or_update()
{
local ip=$1
local stat=1
mysql -vv << EOF
INSERT INTO firewall.kontener (ip) VALUES (INET_ATON('$ip')) ON DUPLICATE KEY UPDATE ts=(NOW());
EOF
stat=$?
return $stat
}

if [ "$(mysql_insert_or_update $IP | grep "Query OK")" = "Query OK, 1 row affected" ]; then
echo "Bekerült az adatbázisba!"
else
echo "Timestamp frissítve!"
fi

Cirka 25%-al gyorsabb mint amikor a SELECT ROW_COUNT(); -os megoldást használtam.

Tranzakciot hasznalhat, hogy atomi muvelet legyen a select majd update, felteve persze ha innodb engine-t hasznal a tablanak.
Egyebket jogos affected rows nem ugyanazt az erteket adja vissza insert es update eseten:
"With ON DUPLICATE KEY UPDATE, the affected-rows value per row is 1 if the row is inserted as a new row, 2 if an existing row is updated, and 0 if an existing row is set to its current values."
https://dev.mysql.com/doc/refman/5.6/en/insert-on-duplicate.html