Vous n'êtes pas identifié(e).
- Contributions : Récentes | Sans réponse
Pages : 1
#1 21/12/2015 15:57:11
- Papychampi
- Membre
Faire un select avec un tableau
Bonjour,
Je dois faire un select avec toutes les valeurs d'un tableau passé en paramètre d'une procédure stocké. Actuellement je passe par:
DECLARE
_ret BOOLEAN;
_save_quantity INTEGER;
_prev_quantity INTEGER;
_my_variable INTEGER;
_sorderid INTEGER;
_ptypeid INTEGER;
_batch INTEGER;
_sdeliveryid_new INTEGER;
_dddd INTEGER;
_pid INTEGER;
_save INTEGER;
_family TEXT;
_hex TEXT;
BEGIN
_ret:=check_sn(_sn);
IF _ret = false
THEN
RETURN FALSE;
END IF;
RAISE LOG '======================================================================';
/* Chercher la candence avec le numéro de série */
IF (_id ISNULL)
THEN
IF (_sn ISNULL)
THEN
RAISE EXCEPTION 'Merci de rentrer une cadence ou un numéro de série';
END IF;
SELECT sdeliveryid FROM product WHERE sn = _sn INTO _id;
IF (_id ISNULL)
THEN
RAISE EXCEPTION 'Aucun produit ne correspond à ce numéro de série';
END IF;
ELSE
SELECT sdeliveryid FROM supplierdeliveries WHERE sdeliveryid = _id INTO _id;
IF (_id ISNULL)
THEN
RAISE EXCEPTION 'Aucune cadence trouvée';
END IF;
END IF;
/* Sélection de la quantité pour vérification */
RAISE LOG 'sn_tab --> %', _sn_tab;
RAISE LOG 'sn_tab_nb --> %', _sn_tab_nb;
_save_quantity = _quantity;
SELECT quantity FROM supplierdeliveries WHERE sdeliveryid = _id INTO _prev_quantity;
RAISE LOG 'sdeliveryid --> %', _id;
IF (_prev_quantity > _quantity)
THEN
IF (_sn_tab ISNULL OR _sn_tab_nb = 0 OR _sn_tab_nb != (_prev_quantity - _quantity))
THEN
RAISE EXCEPTION 'Merci de renseigner les numéros de série des cartes non reçues';
END IF;
SELECT COUNT(sn) FROM product WHERE sn IN (_sn_tab) AND sdeliverid = _id INTO _my_variable; // <--------------- _sn_tab est le problème
IF (_my_variable != _sn_tab_nb)
THEN
RAISE EXCEPTION 'Le(s) numéro(s) de série ne correspond(ent) pas à la cadence indiquée';
END IF;
END IF;
/* Vérification des quantités */
IF _prev_quantity != _quantity
THEN
/* Création d'une nouvelle cadence pour absorber la différence de produit */
SELECT sorderid FROM supplierdeliveries WHERE sdeliveryid = _id INTO _sorderid;
SELECT ptypeid FROM supplierdeliveries WHERE sdeliveryid = _id INTO _ptypeid;
SELECT batch FROM supplierdeliveries WHERE sdeliveryid = _id INTO _batch;
INSERT INTO supplierdeliveries (sorderid, ptypeid, batch) VALUES (_sorderid, _ptypeid, _batch) RETURNING "sdeliveryid" INTO STRICT _sdeliveryid_new;
IF _prev_quantity > _quantity /* Si on en a moins que prévu */
THEN
/* MAJ de la candence initiale */
UPDATE supplierdeliveries SET quantity = _quantity WHERE sdeliveryid = _id;
/* MAJ de la nouvelle candence */
UPDATE supplierdeliveries SET quantity = (_prev_quantity - _quantity) WHERE sdeliveryid = _sdeliveryid_new;
/* Changer status en carte jamais livré */
UPDATE product SET sdeliveryid = _sdeliveryid_new, status = '00000000000000000000000000000101' WHERE sn IN (_sn_tab);
ELSE /* Si on en a plus que prévu */
/* MAJ de la nouvelle candence */
UPDATE supplierdeliveries SET quantity = (_quantity - _prev_quantity), date = _date , deliveryslip = _deliveryslip WHERE sdeliveryid = _sdeliveryid_new;
SELECT ptypeid FROM product WHERE sn = _sn INTO _ptypeid;
SELECT family FROM product_types WHERE ptypeid = _ptypeid INTO _family;
SELECT max(hex_to_int(right( sn, 4))) FROM product WHERE ptypeid IN (SELECT ptypeid AS _ptypeidtab FROM product_types WHERE family = _family) INTO _dddd;
/* Création des nouveaux produits associés à la nouvelle cadence Date = date de livraison et status = carte comandé + carte livrée */
FOR i IN 1 .. (_quantity - _prev_quantity) LOOP
_dddd := _dddd + i;
_hex = right('0000' || int_to_hex(_dddd),4);
_sn := left(_sn, -4) || UPPER(_hex);
/* Insertion */
INSERT INTO product (sdeliveryid, ptypeid, sn, status, date) VALUES (_id, _ptypeid::integer, _sn::text, '00000000000000000000000000000011', _stardate);
END LOOP;
END IF;
END IF;
UPDATE product SET status = '00000000000000000000000000000011', date = _date WHERE sdeliveryid = _id;
RAISE LOG 'sdeliveryid --> %', _id;
UPDATE supplierdeliveries SET date = _date, deliveryslip = _deliveryslip WHERE sdeliveryid = _id;
/* Cloture de la commande */
SELECT sorderid FROM supplierdeliveries WHERE sdeliveryid = _id INTO _pid;
SELECT sdeliveryid FROM supplierdeliveries WHERE date ISNULL AND sorderid = _pid INTO _save;
IF (_save ISNULL)
THEN
UPDATE supplierorders SET enddate = _date WHERE sorderid = _pid;
END IF;
RETURN TRUE;
END;
_sn_tab text[],
_sn_tab_nb integer,
_sn text,
_date date,
_deliveryslip integer,
_quantity integer,
_id integer DEFAULT 0)
RETURNS boolean AS
Donc du coup je voudrais savoirsi il existe un moyen de faire ça et si oui comment faire... Merci beaucoup d'avance pour les réponses
Cordialement
Papychampi
Hors ligne
#2 21/12/2015 20:14:13
- rjuju
- Administrateur
Re : Faire un select avec un tableau
Je pense que vous cherchez l'opérateur ANY. cf http://docs.postgresql.fr/9.3/functions-subquery.html
Par exemple
select * from generate_series(1,10) i where i = any( '{1,4}'::int[]);
i
═══
1
4
(2 rows)
Julien.
https://rjuju.github.io/
Hors ligne
#3 22/12/2015 10:48:07
- Papychampi
- Membre
Re : Faire un select avec un tableau
Bonjour,
Merci de votre réponse.
Cependant le problème persiste. Enfin pas au point de me sortir une erreur non voulu mais le:
SELECT COUNT(sn) FROM product WHERE sdeliveryid = _id AND sn = ANY(_sn_tab) INTO _my_variable;
me retourne 0. Du coup j'ai quand même vérifié si mes valeur étaient bien dans mon tableau et elles y sont ensuite j'ai vérifié si celà ne venais pas du sdeliveryid mais apparemment non... Je me sens tellement près du but!
Cordialement,
Hors ligne
#4 22/12/2015 15:12:34
- rjuju
- Administrateur
Re : Faire un select avec un tableau
Que vous renvoie la requête si vous l'exécutez manuellement ? Par exemple
SELECT * FROM product WHERE sdeliveryid = le_id AND sn = ANY(le_tableau)
Julien.
https://rjuju.github.io/
Hors ligne
#5 22/12/2015 16:54:01
- Papychampi
- Membre
Re : Faire un select avec un tableau
So...
J'ai fais un test en mode manuel... et je pense que le problème ne viens en effet pas du SQL mais bien du PHP puisque ça marche en manuel...
Du coup juste pour être sûr... J'ai une fonction php qui est censé transformé mes tableaux php en tableaux postgresql dont voici le code:
<?php
function to_pg_array($set) {
settype($set, 'array'); // can be called with a scalar or array
$result = array();
foreach ($set as $t) {
if (is_array($t)) {
$result[] = to_pg_array($t);
} else {
$t = str_replace('"', '\\"', $t); // escape double quote
if (! is_numeric($t)) // quote only non-numeric values
$t = '"' . $t . '"';
$result[] = $t;
}
}
return '{' . implode(",", $result) . '}'; // format
}
?>
Est ce que ce bout de code serait à l'origine de mes problèmes?
Hors ligne
#6 22/12/2015 21:30:19
- rjuju
- Administrateur
Re : Faire un select avec un tableau
La fonction me semble fonctionner normalement, mais je ne suis pas du tout expert php. Du côté de la procédure stockée, pouvez-vous afficher le contenu de la variable ? par exemple raise notice '% % %', _sn_tab, _sn_tab[1], array_upper(_sn_tab[1]);
Julien.
https://rjuju.github.io/
Hors ligne
#7 23/12/2015 10:42:41
- Papychampi
- Membre
Re : Faire un select avec un tableau
Bonjour,
Donc j'ai fait ce que tu m'a demandé sauf pour le array_upper parce que ça ne marche pas sur les tableau de text:
{"{\"TOTO#1552EA101__0029
\",\"TOTO#1552EA101__002A\"}"}
{"TOTO#1552EA101__0029
","TOTO#1552EA101__002A"}
Du coup on observe un truc assez interessant on dirait un tableau double dimensions... Puis que quand on regarde bien le deuxième tableau à un bon affichage... hmmm... Celà voudrais dire que le tableau créé par cette fonction serait donc un tableau à deux dimenssions...
Dernière modification par Papychampi (23/12/2015 10:42:58)
Hors ligne
Pages : 1