SQL MariaDB - Select i Update

SQL MariaDB - Select i Update
ZK
  • Rejestracja:około 19 lat
  • Ostatnio:4 miesiące
0

Mam taki problem.
W zapytaniu mam kilka różnych zmiennych - to tylko przykład

Kopiuj
SET @DoZmiany='Napis do zmiany';
SET @WydobytaWartosc='';
SET @WstawianieWartosci='';
SET @ZmianaWartosci='';
SET @PoZmianie='';
SELECT
`pID`,
@DoZmiany:=`pAdres` AS 'Caly napis',
@WydobytaWartosc:=REGEXP_substr(@DoZmiany,'jakies tam wyrazenie REGEX') AS 'Wydobywanie danych',
@WstawianieWartosci:=REGEXP_replace(@WydobytaWartosc,'\\b \\b','_') AS 'wstawianie _',
@PoZmianie:=REGEXP_replace(@DoZmiany,'jakies tam wyrazenie REGEX',@WstawianieWartosci) AS 'Zmiana',
@PoZmianie AS 'Po zmianie'
FROM
`tabela2`

i chciałbym to zapytanie przerobić w taki sposób, aby wybierał jeden rekord, dokonywał na nim potrzebnych zmian i te zmiany UPDATE-ował na stare miejsce

Wynik ma być taki

Kopiuj
Napis_do_zmiany

i to ma się znaleźć w starym miejscu


bla
abrakadaber
abrakadaber
  • Rejestracja:ponad 12 lat
  • Ostatnio:8 miesięcy
  • Postów:6610
2

nie wiem jak inni ale ja nie mam pojęcia o co chodzi


Chcesz pomocy - pokaż kod - abrakadabra źle działa z techniką.
YA
  • Rejestracja:prawie 10 lat
  • Ostatnio:13 dni
  • Postów:2370
1

Przykładowy update do zmiany danych:

Kopiuj
update tabela set stare_miejsce='napis_do_zmiany' where zmienna1=3 and zmienna2='abc';
  1. Opisz swój problem, a nie swoje rozwiązanie problemu
  2. Wstaw przykładową strukturę tabel + dane np. na http://sqlfiddle.com/
ZK
  • Rejestracja:około 19 lat
  • Ostatnio:4 miesiące
0

@abrakadaber nie wiem jak inni ale ja nie mam pojęcia o co chodzi

chodzi o to, że chcę utworzyć JEDNO zapytanie SELECT które pobierze jeden rekord, porobi tam zmiany według powyższego schematu, jak to dokona, to zrobi UPDATE tego rekordu w tym samym podzapytaniu i cykl powtarza się aż nie skończą się rekordy w tabeli

@yarel 1) Opisz swój problem, a nie swoje rozwiązanie problemu

Nie chcę być złośliwy ale jest tak, że wizja tego co chcemy uzyskać prowadzi nas do rozwiązania, uważam to za najwłaściwsze podejście. Bo jeżeli ktoś zabiera się do zrobienia czegoś, to najpierw robi plan jak to ma wyglądać, a potem to realizuje. Czyli jeżeli wiesz co chcę osiągnąć, to najprawdopodobniej szybciej podsuniesz mi rozwiązanie.

Chcesz szczegóły ? no to proszę bardzo - chociaż wydaje mi się, że już powiedziałem to wyżej pod odpowiedzią dla @abrakadaber.

mam jedną tabelę, z jedną kolumną, a w tej kolumnie w pytę rekordów - schematu nie daję, bo to jedna tabela.

W tych rekordach są dane tekstowe które są zapisane wyrazami, a między nimi jest spacja np

Kopiuj
"jeden dwa trzy 123/344 33", 
"jakiś tam ciąg ze spacjami 887 234"

i to są rekordy, dużo rekordów. Teraz chcę zamiast spacji dodać tam znak podkreślenia _ ale TYLKO między wyrazami, bez cyfr [0-9]. Mam napisane wyrażenie regularne które wybiera całe te zdania ale bez liczb i bez znaków specjalnych. np

Kopiuj
"jeden dwa trzy"
"jakiś tam ciąg ze spacjami"

Powyższe zapytanie w pierwszym poście doskonale modyfikuje ten tekst ale nie robi UPDATE w rekordach i chciałbym wiedzieć, jak zapytać takie podzapytanie abym po modyfikacji miał od razu zaktualizowany rekord ?


bla
edytowany 5x, ostatnio: zkubinski
TR
  • Rejestracja:ponad 7 lat
  • Ostatnio:5 dni
  • Lokalizacja:700m n.p.m.
  • Postów:677
0

Możesz to załatwić przez funkcję, w środku której wykonasz te operacje, a samo wywyłanie funkcji to będzie właśnie "jedno zapytanie SQL"

https://mariadb.com/kb/en/create-function/

https://www.javatpoint.com/mariadb-function


DRY > SOLID (nie bierz tego zbyt poważnie)
edytowany 1x, ostatnio: TomRZ
ZK
a czy jest jakiś prostszy sposób ? Z drugiej strony możesz mieć rację, bo funkcja musi zwrócić zmodyfikowany tekst abym mógł zrobić UPDATE
ZK
chciałbym jeszcze zapytać czy w SQL-u da się zrobić funkcję która nic nie zwraca ? Pytam, ponieważ zacząłem zapoznawać się z tematem
TR
To nie ma specjalnie znaczenia, w funkcji możesz wykonać insert, update i zwrócić cokolwiek, chociażby liczbę 1. Nie musisz tej zwracanej wartości nigdzie wykorzystać. Po prostu uruchamiasz funkcje i to wszystko, a że sobie coś zwróci to nie ma zanaczenia. Wykonujesz SELECT FUNKCJA(argumenty); i koniec.
ZK
a czy rozpisałbyś mi w tym poście jak zrobić takie funkcje ? Wiem, że dałeś mi dokumentację ale trochę trudno mi złożyć coś działającego
ZK
  • Rejestracja:około 19 lat
  • Ostatnio:4 miesiące
0

Zrobiłem taką funkcję, bo chcę się nauczyć robić funkcje w SQL-u ale ta funkcja mi nie działa bo mam taki błąd

Kopiuj
Something is wrong in your syntax obok '@zmienna int' w linii 4
Kopiuj
CREATE FUNCTION test()
RETURNS INT DETERMINISTIC
	BEGIN
    	DECLARE @zmienna int;
    	SET @zmienna=1;
    	RETURN @zmienna;
    END;

bla
ZK
już rozwiązałem swój problem - dziękuję wszystkim za pomoc i zaangażowanie.
ZK
  • Rejestracja:około 19 lat
  • Ostatnio:4 miesiące
0

@TomRZ: funkcje są fajne ale wydaje mi się, że funkcja nie spełni moich oczekiwań, ponieważ NA RAZ może zwrócić tylko jedną wartość. No chyba, że powinno się wywołać taką funkcję w pętli ale podczas wywołania tej funkcji musiałbym najprawdopodobniej zrobić tak aby w jednym z argumentów przyjmowała ID rekordu na którym aktualnie ma pracować.

Do tej roboty wydają mi się lepsze procedury, bo mogą zwracać na raz wiele wartości.

No ale pytanie czy ktoś by mi tu podpowiedział, jak napisać pętlę dla funkcji lub procedury w SQL-u dla MariaDB ? Bo przyznam szczerze, że ma dość specyficzny zapis, wiele elementów wzajemnie się wyklucza i trzeba cały dzień spędzić aby przebić się przez gąszcz informacji - dokumentacja ma bardzo wiele do życzenia.

Przykłady wykluczeń chociażby przy deklaracji zmiennych, przy inicjalizacji zmiennych jakimiś wartościami np

  1. Dla funkcji
  • deklaruje się zmienną o tak
Kopiuj
DECLARE nazwa_zmiennej typ;
  • inicjalizuje się tak
Kopiuj
SET nazwa_zmiennej=wartość;
  1. Gdy nie ma funkcji
  • deklaruje się zmienną (niezainicjalizowaną) o tak
Kopiuj
SET @zmienna=""
  • inicjalizuje się tak
Kopiuj
@zmienna:=wartość;

I weź tu się połap człowieku... Poza tym mam wrażenie, że nie za bardzo lubicie dzielić się wiedzą.


bla
edytowany 3x, ostatnio: zkubinski
TR
W jednej funkcji możesz zrobić wiele operacji insert/update. Jeszcze raz Ci tlumaczę, że to co zwracasz z funkcji, nie ma kompletnie żadnego znaczenia.
ZK
rozumiem to, ale może podasz jakiś przykład jak to zrobić ?
ZK
  • Rejestracja:około 19 lat
  • Ostatnio:4 miesiące
0

dla wszystkich którzy kiedykolwiek będą się gryźli z pisaniem własnych funkcji, podaję wzór jak napisać własną funkcję. Bo tutaj niektórzy wyznają zasadę "wiem ale nie powiem" i jeszcze mają dużo do powiedzenia, a ja bardzo ale to bardzo nie znoszę takich mądrali.

To działa na xampp silnik MariaDB

  1. Najprostsza funkcja
Kopiuj
DELIMITER //
CREATE FUNCTION test(zmienna varchar(20))
RETURNS varchar(20) DETERMINISTIC
    BEGIN
        RETURN zmienna;
    END; //
DELIMITER ;

SELECT test('udalo sie') AS 'Wywolanie funkcji';
  1. Funkcja która wywołuje jakąś wbudowaną metodę SQL-ową w tym przypadku REGEXP_substr()
Kopiuj
DELIMITER //
CREATE FUNCTION test() 
RETURNS varchar(100) DETERMINISTIC READS SQL DATA
	BEGIN 
    	DECLARE zmienna varchar(100) DEFAULT ''; 
        SET zmienna=(
            SELECT 
            REGEXP_substr(`pAdres`,'REGEX') 
            FROM `tabela2` 
            WHERE `pID`=22); 
       	RETURN zmienna; 
   	END; //
DELIMITER ;

SELECT test() AS 'Wywolanie funkcji';

DROP FUNCTION test; --UWAGA usuwanie jest opcjonalne


bla
edytowany 3x, ostatnio: zkubinski
YA
  • Rejestracja:prawie 10 lat
  • Ostatnio:13 dni
  • Postów:2370
0
zkubinski napisał(a):

...

@yarel 1) Opisz swój problem, a nie swoje rozwiązanie problemu

Nie chcę być złośliwy ale jest tak, że wizja tego co chcemy uzyskać prowadzi nas do rozwiązania, uważam to za najwłaściwsze podejście. Bo jeżeli ktoś zabiera się do zrobienia czegoś, to najpierw robi plan jak to ma wyglądać, a potem to realizuje. Czyli jeżeli wiesz co chcę osiągnąć, to najprawdopodobniej szybciej podsuniesz mi rozwiązanie.

Wizję może masz w swojej głowie, ale jeśli nie potrafisz jej klarownie przekazać, to ciężko oczekiwać sensownych porad. Ogólne opisy -> ogólne rozwiązania.

Chcesz szczegóły ? no to proszę bardzo - chociaż wydaje mi się, że już powiedziałem to wyżej pod odpowiedzią dla @abrakadaber.

W tych rekordach są dane tekstowe które są zapisane wyrazami, a między nimi jest spacja np

Kopiuj
"jeden dwa trzy 123/344 33", 
"jakiś tam ciąg ze spacjami 887 234"

I z tego chcesz uzyskać coś innego?

Kopiuj
"jeden dwa trzy"
"jakiś tam ciąg ze spacjami"

Nie chce mi się dumać nad regexpami (zwłaszcza, że napisałeś, że takowe masz i działają tak jak chcesz), bo pewnie problem i tak jest inny niż opisujesz, ale wygląda, że można to zrobić jednym update: https://dbfiddle.uk/?rdbms=mariadb_10.4&fiddle=712daab710a3d48f02cccd8e1d5f3551

W skrócie:

  • funkcję możesz wywołać na całej tabeli (zbiorze danych) i jako argumenty przekazać wartości z "bieżącego" wiersza.
  • wartość zwróconą przez funkcję możesz użyć do aktualizacji "bieżącego" wiersza
ZK
ogólnie wątek można już zamknąć, bo ze wszystkim sobie poradziłem.
ZK
patrząc na twojego linka co mi dałeś, widzisz, gdybyś odezwał się w czasie trwania wątku, to zrobiłbym to krótko tak jak ty, a tak, to mam funkcję która to robi...

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.