Vous n'êtes pas identifié(e).
Pages : 1
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...
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?
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,
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
Et bien apparemment ce n'est pas le cas...
Bonjour à tous!
j'ai une une procédure stockée qui créé des produits dans mes tables tout est expliquer ici http://forums.postgresql.fr/viewtopic.php?id=3716 et du coup j'ai un petit problème... Il s'avère que lors de la création de la deuxième cadence le numéro récupéré est le dernier mais d'avant la création de la commande...
Du coup je viens implorer votre aide... Comment fait on pour gérer les transactions en procédures stockées...?
Cordialement,
Papychampi
Bon bah du coup un gros GG à edlm qui m'a bien aidé sur coup là!
Ok merci! C'est cool ça marche!
Seulement j'ai un petit soucis sur une requête qui pourtant me parait basique:
DECLARE
i integer;
j integer;
_sorderid integer;
_sdeliveryid integer;
_dddd integer;
_test integer;
_ret boolean;
_hex text;
_family text;
_ptypeidtab integer[];
BEGIN
/* Création de la commande + Récupère l'identifiant */
INSERT INTO supplierorders (orderform, startdate, quantity, supplier) VALUES (_orderform, _stardate, _total, _supplier) RETURNING "sorderid" INTO STRICT _sorderid;
FOR j IN 1 .. _cadences LOOP
/* Vérification du numéro de série */
_ret := check_sn(_sn[j]);
/* Détermination du numéro d'incrément pour la famille de produit */
SELECT family AS _family FROM product_types WHERE ptypeid = _ptypeid[j]; -- CETTE LIGNE LA BUG
SELECT max(x'right( _sn[j], 4)'::integer) AS _dddd FROM product WHERE ptypeid IN (SELECT ptypeid AS _ptypeidtab FROM product_types WHERE family = _family) ;
/* Si c'est le premier produit on commence la numérotation à 1 */
IF (_dddd IS NULL)
THEN
_dddd = 0;
END IF;
/* Création de la cadence + Récupère l'identifiant */
INSERT INTO supplierdeliveries (sorderid, ptypeid, batch, quantity) VALUES (_sorderid, _ptypeid[j]::integer, _batch[j]::integer, _quantity[j]::integer) RETURNING "sdeliveryid" INTO STRICT _sdeliveryid;
/* Création des produits liés à la cadence */
FOR i IN 1 .. _quantity[j] LOOP
_hex = right('0000' || int_to_hex(_dddd + i),4);
_sn[j] := left(_sn[j], -4) || UPPER(_hex);
/* Insertion */
INSERT INTO product (sdeliveryid, ptypeid, sn, status, date) VALUES (_sdeliveryid, _ptypeid[j]::integer, _sn[j]::text, 'Ordered', _stardate);
END LOOP;
END LOOP;
END;
Avec ce code d'erreur...
la requête n'a pas de destination pour les données résultantes
Mais ce que je comprend pas c'est que quand je le fait à la main ça marche donc je pense que ce n'est qu'une question d'indice... Les tableaux commencent à partir de 1 ou 0 en postgresql?
Bien sûr:
CREATE TABLE product_types
(
ptypeid integer NOT NULL DEFAULT nextval('"Product_Types_PTypeId_seq"'::regclass),
family text,
name text,
fab text,
version text,
subversion text,
pn text,
description text,
CONSTRAINT "PK_Product_Type" PRIMARY KEY (ptypeid)
)
WITH (
OIDS=FALSE
);
ALTER TABLE product_types
OWNER TO postgres;
Bonjour,
Je fais des procédures stockées qui sont censée créer des commandes... Seulement les numéros de séries des produits doivent être incrémenté de la manière suivante:
XXXXXXXXXXXXX_0001
XXXXXXXXXXXXX_0002
XXXXXXXXXXXXX_0003
XXXXXXXXXXXXX_0004
XXXXXXXXXXXXX_0005
XXXXXXXXXXXXX_0006
XXXXXXXXXXXXX_0007
XXXXXXXXXXXXX_0008
XXXXXXXXXXXXX_0009
XXXXXXXXXXXXX_000A
XXXXXXXXXXXXX_000B
XXXXXXXXXXXXX_000C
XXXXXXXXXXXXX_000D
XXXXXXXXXXXXX_000E
XXXXXXXXXXXXX_000F
XXXXXXXXXXXXX_0010
Pour cela j'utilise:
max(x'right( sn, 4)'::integer)
qui récupère les 4 derniers caractères du dernier numéro de série rentré par l'utilisateur
Voici la définition de la table product_types:
PK PTypeId Clé primaire
Family Famille principale du produit (US-CORE, US-ICC, US-RACK, US-8I-RJ)
Name Désignation commerciale (US-COREV3, US-ICC2)
Fab Type de fabrication (FAB_A, FAB_B,...)
Version Version majeure du produit
SubVersion Version additionnelle du produit
PN Part Number associé à l’état matériel du Produit (ne prend pas en compte des personnalisations logicielles comme l’ajout de licences)
Description Description du produit
Le truc étant que le numéro de série doit augmenter selon le dernier de la famille et pour une famille je peux avoir plusieurs PTypeId. Du coup, je suis obligé de faire un
SELECT family AS _family FROM product_types WHERE ptypeid = _ptypeid;
Qui me récupère la famille pour un type de produit et ensuite faire un:
SELECT ptypeid AS _ptypeidtab FROM product_types WHERE family = _family;
qui me récupère tout les PTypeId qui ont cette famille...
et à partir de là je dois récupérer le plus haut incrément que je concatène au reste du numéro de série...
Je sais pas si je suis précis en fait...
En tous cas merci de m'aider!
Bonjour,
Je vais essayer d'être plus précis...
J'ai une première requête qui me retourne un tableau contenant plusieurs id... et je dois faire une requête en faisant un WHERE id = {Le contenu de TOUT le tableau}
Je sais pas si c'est plus précis... Par l'exemple ce sera plus précis:
SELECT family AS _family FROM product_types WHERE ptypeid = _ptypeid; // retourne une chaine
SELECT ptypeid AS _ptypeidtab FROM product_types WHERE family = _family; // retourne un tableau
SELECT max(x'right( sn, 4)'::integer) AS _dddd FROM products WHERE ptypeid = _ptypeidtab; // Doit faire une requête avec tout le contenu du tableau
PS: C'est dans une fonction PGSQL mais la question est plus d'ordre général que d'ordre de PGSQL
Cordialement,
Bonjour à tous,
Je souhaite faire une requête avec un tableau... En fait je dois faire une requête avec toutes les données stockées dans les colonnes de ce tableau... Je voudrais savoir si c'est possible et si oui de quelle manière?
Cordialement,
Papychampi
Bonjour à tous!
Bon je vous explique un peu mon problème... Je créé un site web pour la gestion des stocks d'une entreprise... Pour la gestion des statuts des produits nous avons opté pour le faire avec des bits string... Littéralement des chaines de bits... Seulement voilà je dois pouvoir être capable de changer seulement un bit dans cette chaîne sans touché aux autres...
Mon responsable m'a dit qu'avec une XOR il n'y aurais pas de soucis... (BTW si il n'y en avait pas je ne serais pas là ) Seulement je ne vois absolument pas comment faire...
Si quelqu'un peux me mettre sur la piste ce serait cool à lui!
Merci à vous et Bonne journée,
Papychampi
Hmmm....
C'est très intéressant ce que vous me dites là! Bon du coup c'est bon ça marche... Cependant j'ai remarqué un petit bug chez moi, enfin, pas un bug mais un effet non désirer... La partie Hex doit être codé sur 4 chars quoi qu'il arrive... Mais du coup quand je suis au tout début bah je me retrouve avec des chaines de 1 voir 2 chars ce qui ne doit pas arriver...
Comment faire en sorte qu'il y ai bien 4 chars a chaque fois pour mes nombres hex genre "0001"
En tous cas merci de m'aider
Cordialement,
Bonjour,
Je créé une fonction depuis pgadmin 3 et lorsque je veux la submit il me dit qu'il y a un problème... Du coup je vous donne le code...
DECLARE
i integer;
j integer;
_sorderid integer;
_sdeliveryid integer;
_ret boolean;
_save integer;
_sn text;
BEGIN
INSERT INTO supplierorders (orderform, startdate, quantity, supplier) VALUES (_orderform, _stardate, _total, _supplier) RETURNING "sorderid" INTO STRICT _sorderid;
FOR j IN 1 .. _cadences LOOP
INSERT INTO supplierdeliveries (sorderid, ptypeid, batch, quantity) VALUES (_sorderid, _ptypeid[j]::integer, _batch[j]::integer, _quantity[j]::integer) RETURNING "sdeliveryid" INTO STRICT _sdeliveryid;
_sn := _sn1[j] || _sn2[j];
SELECT check_sn(_sn) into _ret;
IF _ret = false
THEN
RETURN FALSE;
END IF;
FOR i IN 1 .. _quantity[j] LOOP
/* Conquaténation */
_sn := _sn1[j] || _sn2[j];
/* Insertion */
INSERT INTO product (sdeliveryid, ptypeid, sn, status, date) VALUES (_sdeliveryid, _ptypeid[j]::integer, _sn::text, 'Commandées', _date);
/* Ajout de la valeur Hexa */
SELECT hex_to_int(_sn2[j]) INTO _save;
_save = _save + 1;
SELECT int_to_hex(_save) INTO _sn2[j];
END LOOP;
END LOOP;
RETURN TRUE;
END;
Et le message d'erreur
Une erreur s'est produite:
ERREUR: erreur de syntaxe sur ou près de "["
LINE 31: SELECT int_to_hex(_save) INTO _sn2[j];
^
Si vous pouviez éclairer ma petite lanterne...
Bonjour,
Voici le code de ma fonction SQL:
CREATE OR REPLACE FUNCTION add_cmd_gen(
_cadences integer,
_orderform integer,
_total integer,
_batch integer,
_stardate date,
_date date,
_supplier text,
_sn text,
_quantity integer[],
_ptypeid integer[])
RETURNS boolean AS
$BODY$DECLARE
i integer;
j integer;
BEGIN
RAISE LOG 'Création de la commande générale...';
SELECT check_sn16(_orderform);
IF (_orderform ~ '^CC[0-9]{2}(0[1-9]|1[0-2])(00[1-9]|0[1-9][0-9]|[1-9][0-9]{2})$')
THEN
IF (_supplier ~ '^[A-Z]+$')
THEN
IF (_startdate ~ '^(199[6-9]|[2-9][0-9]{3})-(0[1-9]|1[0-2])$')
THEN
IF (_quantity ~ '^[0-9]+$')
THEN
INSERT INTO supplierorders (orderform, startdate, quantity, supplier) VALUES (_orderform, _startdate, _total, _supplier) RETURNING sorderid;
RAISE LOG 'Terminé';
ELSE
RAISE LOG 'La quantité n est pas correct!';
END IF;
ELSE
RAISE LOG 'La date n est pas correct!';
END IF;
ELSE
RAISE LOG 'Le nom du fournisseur n est pas correct!';
END IF;
ELSE
RAISE LOG 'La date n est pas correct!';
END IF;
RAISE LOG 'Création des sous-commandes...';
j = 0;
WHILE _batch[j] IS NOT NULL LOOP
IF (_sorderid ~ '^[0-9]+$')
THEN
IF (_ptypeid[j] ~ '^[0-9]+$')
THEN
IF (_batch[j] ~ '^[0-9]+$')
THEN
IF (_quantity[j] ~ '^[0-9]+$')
THEN
INSERT INTO supplierdeliveries (sorderid, ptypeid, batch, quantity) VALUES (_sorderid, _ptypeid[j], _batch[j], _quantity[j]);
i = 0;
FOR i IN REVERSE 0 .. _quantity LOOP
INSERT INTO products (sdeliveryid, ptypeid, sn, status, date) VALUES (_sdeliveryid, _ptypeid, _sn, 'Commandées', GETDATE());
END LOOP;
ELSE
RAISE LOG 'La quantité n est pas correcte';
END IF;
ELSE
RAISE LOG 'Le numéro de lot n est pas correcte';
END IF;
ELSE
RAISE LOG 'Le type de produit n est pas correcte';
END IF;
ELSE
RAISE LOG 'La date n est pas correcte';
END IF;
j = j + 1;
END LOOP;
RAISE LOG 'Terminé';
END;$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION add_cmd_gen(integer, integer, integer, integer, date, date, text, text, integer[], integer[])
OWNER TO postgres;
Bonjour,
Je développe une application en php/postgresql et je voudrais faire passer un tableau dans une de mes procédures stockée. Seulement Php me retourne cette erreur...
Notice: Array to string conversion in [...] commandes.php on line 47
Du coup je voudrais savoir quelle est la syntaxe correcte pour passer des tableaux en paramètres de fonctions postgresql...
if (isset($_POST['submit'])){
if ($_POST['submit']){
$qua = array();
for ($i=0;$i<$_POST['nb_choix'];$i++){
$qua[$i] = $_POST['quantity' . $i];
}
$bat = array();
for ($i=0;$i<$_POST['nb_choix'];$i++){
$bat[$i] = $_POST['batch' . $i];
}
$sn = array();
for ($i=0;$i<$_POST['nb_choix'];$i++){
$sn[$i] = $_POST['sn' . $i];
}
for ($i = 0; $i < $_POST['nb_choix'];$i++){
$res = pg_query_params($conn, "SELECT * FROM product_types WHERE ptypeid = $1", array($_POST['batch' . $i]));
$data = pg_fetch_row($res);
$corps = str_ireplace("V", "", $data[4]);
$v[$i] = str_ireplace("R", "", $corps);
$save = ltrim($data[3], "FABfab");
$f[$i] = str_ireplace(" ", "", $save);
$d[$i] = $_POST['d' . $i];
$n[$i] = $_POST['n' . $i];
}
$sql = "SELECT add_cmd_gen(" . $_POST['nb_choix'] . ", " . $_POST['orderform'] . ", " . $_POST['total'] . ", " . $_POST['orderform'] . ", " . $bat . ", " . $_POST['startdate'] . ", " . $_POST['startdate'] . ", " . $_POST['supplierdeliveries'] . ", " . $sn . ", " . $_POST['supplierdeliveries'] . ", " . $qua . ", " . $ptypeid . ")";
$res = pg_query($conn, $sql);
Bonjour,
Déjà merci de votre réponse. Je voudrais juste savoir parce que ça m'intrigue pas mal aussi c'est que ma RegEx retourne toujours false... Même pour des chaines de caractères qui sont correctes...
Du genre celle ci:
AZ#2323BA765AEF4
Du coup pour que vous puissiez m'aider voici comment c'est fait:
NN#YYWWTFVVVDDDD
NN : A à Z
YY : 0 - 9
WW : 0-5 puis 0-9
T: A à D ou 4
F: A à F
VVV: 0 à 9
DDDD A à F / 0 à 9
Informations Utiles:
Version: 9.4
Logiciel: PgAdminIII
Autre langage: PHP / Javascript
Message:
Bonjour à tous,
J'ai une petite fonction qui marcherais si ma variable était reconnue comme telle et pas comme une colonne... En gros cette fonction permet de vérifier le formatage d'un numéro de série...
CREATE OR REPLACE FUNCTION check_sn("_SN" text)
RETURNS boolean AS
$BODY$BEGIN
IF ('^[A-Z]{2}\#[0-9]{2}[0-5][0-9][A-D4][A-F][0-9]{3}[A-F0-9]{4}$' ~ _SN)
THEN
RAISE LOG 'Checking SN: OK!';
RETURN true;
ELSE
RAISE LOG 'Checking SN: FAILED!';
RETURN false;
END IF;
END;$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION check_sn(text)
OWNER TO postgres;
Pages : 1