requete pour spliter une colonne

requete pour spliter une colonne - SQL/NoSQL - Programmation

Marsh Posté le 14-10-2008 à 18:05:56    

Bonjour,
 
j'ai une table dont la structure est la suivante:
 
 

Code :
  1. TRolePers
  2. {
  3.   idPers(int32)
  4.   Role(varchar50)
  5. }Et comme vous vous en douter, les lignes contiennent ceci:


 

Code :
  1. 1|RespX,RespY
  2. 2|Admin
  3. 3|RespX, RespZ


etc...Est-il possible d'avoir une requête dont le résultat serait ceci sans passer par une table temporaire ?
sachant que dans le colonne role je peux avoir 0 ou n valeur;
 

Code :
  1. 1|RespX
  2. 1|RespY
  3. 2|Admin
  4. 3|RespX
  5. 3|RespZ


 
merci

Reply

Marsh Posté le 14-10-2008 à 18:05:56   

Reply

Marsh Posté le 14-10-2008 à 21:10:28    

Selon ton SGBD il pourrait éventuellement y avoir des fonction intégrées qui pourraient t'aider.
 
Mais sinon, pas de table temporaire. Un bête PS te permettra sans problème de faire ça avec n'importe quel SGBD qui sait faire des PS.
 
PS : Règle numéro 1 = toujours dire sur quel SGBD on a le problème, ça change trop d'un soft à l'autre, surtout pour des trucs comme ça qui ne sont pas régis par la norme SQL.


Message édité par MagicBuzz le 14-10-2008 à 21:11:22
Reply

Marsh Posté le 15-10-2008 à 11:41:36    

désolé j'avais oublier de preciser je suis sous oracle (9i et 10g);
un PS ???

Reply

Marsh Posté le 15-10-2008 à 11:55:42    

une
 
Procédure Stockée.
 
Du PL/SQL quoi

Reply

Marsh Posté le 15-10-2008 à 11:59:04    

Dans ton cas il faudra passer par un truc bien gore d'Oracle, qui s'appelle les tables PIPELINED.
 
En gros, c'est une fonction qui retourne une table, et que tu appelles avec la syntaxe pourrave :
 

Code :
  1. SELECT *
  2. FROM TABLE(mafonction(mesparamètres))


 
T'as pas de pot de bosser avec Oracle, parceque c'est clairement naze leur implémentation mais bon.
Un petit exemple qui peut éventuellement te donner quelques pistes :
 

Code :
  1. CREATE OR REPLACE
  2. TYPE GEDTE_ROW AS OBJECT
  3. (
  4.  CODSOC  INTEGER,
  5.  LIB1    VARCHAR2(30 CHAR),
  6.  LIB2    VARCHAR2(30 CHAR),
  7.  LIB3    VARCHAR2(30 CHAR),
  8.  LIB4    VARCHAR2(30 CHAR),
  9.  LIB5    VARCHAR2(30 CHAR),
  10.  LIB6    VARCHAR2(30 CHAR),
  11.  LIB7    VARCHAR2(30 CHAR),
  12.  LIB8    VARCHAR2(30 CHAR),
  13.  LIB9    VARCHAR2(30 CHAR),
  14.  LIB10   VARCHAR2(30 CHAR),
  15.  LIB11   VARCHAR2(30 CHAR),
  16.  LIB12   VARCHAR2(30 CHAR),
  17.  LIB13   VARCHAR2(30 CHAR),
  18.  LIB14   VARCHAR2(30 CHAR),
  19.  LIB15   VARCHAR2(30 CHAR),
  20.  LIB16   VARCHAR2(30 CHAR),
  21.  LIB17   VARCHAR2(30 CHAR),
  22.  LIB18   VARCHAR2(30 CHAR),
  23.  LIB19   VARCHAR2(30 CHAR),
  24.  LIB20   VARCHAR2(30 CHAR),
  25.  DAT1    VARCHAR2(8 CHAR),
  26.  DAT2    VARCHAR2(8 CHAR),
  27.  DAT3    VARCHAR2(8 CHAR),
  28.  DAT4    VARCHAR2(8 CHAR),
  29.  DAT5    VARCHAR2(8 CHAR),
  30.  NUM01   INTEGER,
  31.  NUM02   INTEGER,
  32.  NUM03   INTEGER,
  33.  NUM04   INTEGER,
  34.  NUM05   INTEGER,
  35.  NUM06   INTEGER,
  36.  NUM07   INTEGER,
  37.  NUM08   INTEGER,
  38.  NUM09   INTEGER,
  39.  NUM10   INTEGER,
  40.  VAL01   NUMBER,
  41.  VAL02   NUMBER,
  42.  VAL03   NUMBER,
  43.  VAL04   NUMBER,
  44.  VAL05   NUMBER,
  45.  VAL06   NUMBER,
  46.  VAL07   NUMBER,
  47.  VAL08   NUMBER,
  48.  VAL09   NUMBER,
  49.  VAL10   NUMBER,
  50.  VAL11   NUMBER,
  51.  VAL12   NUMBER,
  52.  VAL13   NUMBER,
  53.  VAL14   NUMBER,
  54.  VAL15   NUMBER,
  55.  VAL16   NUMBER,
  56.  VAL17   NUMBER,
  57.  VAL18   NUMBER,
  58.  VAL19   NUMBER,
  59.  VAL20   NUMBER
  60. );
  61.  
  62. CREATE OR REPLACE
  63. TYPE GEDTE_TABLE AS TABLE OF GEDTE_ROW;
  64.  
  65. CREATE OR REPLACE FUNCTION get_vue (p_vue IN VARCHAR2, p_codsoc IN INTEGER)
  66.   RETURN gedte_table PIPELINED
  67. IS
  68.   v_requete   VARCHAR2 (500);
  69.   c1          sys_refcursor;
  70.   out_rec     gedte_row;
  71. BEGIN
  72.  
  73. -- Initialisation de l'objet out_rec ( Object Type Constructor Method )
  74.   out_rec :=
  75.      gedte_row (NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  76.                 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  77.                 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  78.                 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  79.                 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  80.                 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  81.                 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
  82.                );
  83.  
  84. -- Ouverture du curseur SQL Dynamique
  85.   OPEN c1 FOR 'select * from ' || p_vue || ' where codsoc=' || p_codsoc;
  86.  
  87.   LOOP
  88.      FETCH c1
  89.       INTO out_rec.codsoc, out_rec.lib1, out_rec.lib2, out_rec.lib3,
  90.            out_rec.lib4, out_rec.lib5, out_rec.lib6, out_rec.lib7,
  91.            out_rec.lib8, out_rec.lib9, out_rec.lib10, out_rec.lib11,
  92.            out_rec.lib12, out_rec.lib13, out_rec.lib14, out_rec.lib15,
  93.            out_rec.lib16, out_rec.lib17, out_rec.lib18, out_rec.lib19,
  94.            out_rec.lib20, out_rec.dat1, out_rec.dat2, out_rec.dat3,
  95.            out_rec.dat4, out_rec.dat5, out_rec.num01, out_rec.num02,
  96.            out_rec.num03, out_rec.num04, out_rec.num05, out_rec.num06,
  97.            out_rec.num07, out_rec.num08, out_rec.num09, out_rec.num10,
  98.            out_rec.val01, out_rec.val02, out_rec.val03, out_rec.val04,
  99.            out_rec.val05, out_rec.val06, out_rec.val07, out_rec.val08,
  100.            out_rec.val09, out_rec.val10, out_rec.val11, out_rec.val12,
  101.            out_rec.val13, out_rec.val14, out_rec.val15, out_rec.val16,
  102.            out_rec.val17, out_rec.val18, out_rec.val19, out_rec.val20;
  103.  
  104.      EXIT WHEN c1%NOTFOUND;
  105.      PIPE ROW (out_rec);
  106.   END LOOP;
  107.  
  108.   CLOSE c1;
  109.  
  110.   RETURN;
  111. END get_vue;
  112. /

Reply

Marsh Posté le 15-10-2008 à 16:29:18    

j'ai essayer ceci
 

Code :
  1. CREATE OR REPLACE type s_str AS Object (str1 number,str Varchar2(227))
  2. /
  3. CREATE OR REPLACE type tab_str AS TABLE of s_str
  4. /
  5. CREATE OR REPLACE FUNCTION tab2Str2
  6. ( p_str   Varchar2,
  7.   p_str1 number,
  8.   p_sep   Varchar2 DEFAULT ','
  9. ) RETURN  tab_str
  10. PIPELINED
  11. IS
  12.   l_tab dbms_utility.uncl_array;
  13.   l_tablen     number;
  14. Begin
  15.   dbms_utility.comma_to_table(REPLACE(p_str,p_sep,','), l_tablen, l_tab);
  16.   FOR i IN 1..l_tablen Loop
  17.     pipe row(s_str(l_tab(i)));
  18.      pipe row(s_str(l_tab(i)));
  19.   End Loop;
  20.   --
  21.   RETURN ;
  22. End;
  23. /
  24. SELECT * FROM TABLE( select idPers,tab2Str2(Role,';') from TRolePers where Role like '%;%')


 
mais ça ne fonctionne pas,
je suis vraiment perdu

Reply

Marsh Posté le 15-10-2008 à 16:37:13    

euh... c'est moi ou tu as fait un copier/coller d'un truc sans même comprendre ce qu'il fait ?
 
parceque là ça fait non seulement pas ce que tu tentes de faire, mais en plus tu l'appelles même pas correctement.
 
ps : et dit pas "ça marche pas". donne l'erreur et/ou le comportement obtenu contre celui attendu


Message édité par MagicBuzz le 15-10-2008 à 16:38:16
Reply

Marsh Posté le 15-10-2008 à 16:56:57    

j'avais rajouter une variable str1 pour le id mais ça ne fonctionne pas donc je l'ai enlever
 

Code :
  1. CREATE OR REPLACE type s_str AS Object (str Varchar2(227))
  2. /
  3. CREATE OR REPLACE type tab_str AS TABLE of s_str
  4. /
  5. --DROP TYPE tab_str
  6. CREATE OR REPLACE FUNCTION tab2Str2
  7. ( p_str   Varchar2,
  8.   p_sep   Varchar2 DEFAULT ','
  9. ) RETURN  tab_str
  10. PIPELINED
  11. IS
  12.   l_tab dbms_utility.uncl_array;
  13.   l_tablen     number;
  14. Begin
  15.   dbms_utility.comma_to_table(REPLACE(p_str,p_sep,','), l_tablen, l_tab);
  16.   FOR i IN 1..l_tablen Loop
  17.      pipe row(s_str(l_tab(i)));
  18.   End Loop;
  19.   --
  20.   RETURN ;
  21. End;
  22. /


 
et en faite il me met cette erreur quand je fais le select
 

Citation :


ORA-02324: more than one column in the SELECT list of THE subquery  


 
en faite je l'ai tester sans mettre le idpers dans la requete, il me met tout colonne mais moi je voulais l'idpers avec et la sa bugue;
sa ne fonctionne meme pas si j'ai plus d'une ligne dans ma table,il faut une seule ligne sinon j'ai ce message
 

Citation :


ORA-01427: single-row subquery returns more than one row  


Message édité par donny3 le 15-10-2008 à 16:57:40
Reply

Marsh Posté le 15-10-2008 à 17:02:37    

normal.
 
dans la fonction, fait un premier curseur qui récupère ligne par ligne les données de ta table.
 
et à l'intérieur, fait le découpage.
 
et au niveau unitaire, fait les pipe des lignes générées.
 
et ça devrait marcher.
 

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed