ban

Agrégation de String 

Dernièrement j'ai été amené à effectuer une agrégation de String sur Oracle 10g. Apparemment c'est directement possible sur la 11g, par contre il faut créer la fonction sois-même pour la 10g.
La solution a été trouvé sur Oracle-Base.

Imaginons une table:

DEPTNO ENAME
---------- ----------
20 SMITH
30 ALLEN
30 WARD
20 JONES
30 MARTIN
30 BLAKE
10 CLARK
20 SCOTT
10 KING
30 TURNER
20 ADAMS
30 JAMES
20 FORD
10 MILLER


La question est comment obtenir un résultat comme:
20 SMITH, SCOTT, FORD, ...
30 ALLEN, WARD, ...


Sur la 11g release 2, c'est très simple:
SELECT deptno, LISTAGG(ename, ',') WITHIN GROUP (ORDER BY ename) AS employees
FROM emp
GROUP BY deptno;


donne comme résultat:

DEPTNO EMPLOYEES
---------- --------------------------------------------------
10 CLARK,KING,MILLER
20 ADAMS,FORD,JONES,SCOTT,SMITH
30 ALLEN,BLAKE,JAMES,MARTIN,TURNER,WARD



Si vous utilisez la 10g, il est possible de faire la même chose après avoir compilé ces instructions:

CREATE OR REPLACE TYPE t_string_agg AS OBJECT
(
g_string VARCHAR2(32767),

STATIC FUNCTION ODCIAggregateInitialize(sctx IN OUT t_string_agg)
RETURN NUMBER,

MEMBER FUNCTION ODCIAggregateIterate(self IN OUT t_string_agg,
value IN VARCHAR2 )
RETURN NUMBER,

MEMBER FUNCTION ODCIAggregateTerminate(self IN t_string_agg,
returnValue OUT VARCHAR2,
flags IN NUMBER)
RETURN NUMBER,

MEMBER FUNCTION ODCIAggregateMerge(self IN OUT t_string_agg,
ctx2 IN t_string_agg)
RETURN NUMBER
);
/
SHOW ERRORS


CREATE OR REPLACE TYPE BODY t_string_agg IS
STATIC FUNCTION ODCIAggregateInitialize(sctx IN OUT t_string_agg)
RETURN NUMBER IS
BEGIN
sctx := t_string_agg(NULL);
RETURN ODCIConst.Success;
END;

MEMBER FUNCTION ODCIAggregateIterate(self IN OUT t_string_agg,
value IN VARCHAR2 )
RETURN NUMBER IS
BEGIN
SELF.g_string := self.g_string || ',' || value;
RETURN ODCIConst.Success;
END;

MEMBER FUNCTION ODCIAggregateTerminate(self IN t_string_agg,
returnValue OUT VARCHAR2,
flags IN NUMBER)
RETURN NUMBER IS
BEGIN
returnValue := RTRIM(LTRIM(SELF.g_string, ','), ',');
RETURN ODCIConst.Success;
END;

MEMBER FUNCTION ODCIAggregateMerge(self IN OUT t_string_agg,
ctx2 IN t_string_agg)
RETURN NUMBER IS
BEGIN
SELF.g_string := SELF.g_string || ',' || ctx2.g_string;
RETURN ODCIConst.Success;
END;
END;
/
SHOW ERRORS


CREATE OR REPLACE FUNCTION string_agg (p_input VARCHAR2)
RETURN VARCHAR2
PARALLEL_ENABLE AGGREGATE USING t_string_agg;
/
SHOW ERRORS



Le résultat est alors le même en entrant la requête:
SELECT deptno, string_agg(ename) AS employees
FROM emp
GROUP BY deptno;

DEPTNO EMPLOYEES
---------- --------------------------------------------------
10 CLARK,KING,MILLER
20 SMITH,FORD,ADAMS,SCOTT,JONES
30 ALLEN,BLAKE,MARTIN,TURNER,JAMES,WARD

3 rows selected.

[ Ajouter un commentaire ] ( ( 44 vues ) ) Lien permanent ( 3 / 230 )
Utiliser un fichier de logs avec Windows VBScript 

Voici une procédure permettant d'utiliser facilement un fichier log dans vos scripts VBScript:


Sub Log(pMessage)
Dim objFSO, objOutFile, sWorkingFileName, today
Const FOR_APPENDING = 8

sWorkingFileName = "log.txt"
Set objFSO = CreateObject("Scripting.FileSystemObject")
If objFSO.FileExists(sWorkingFileName) Then
Set objOutFile = objFSO.OpenTextFile(sWorkingFileName, FOR_APPENDING)
Else
Set objOutFile = objFSO.CreateTextFile(sWorkingFileName)
End If
today = Year(Now) & "/" & Right("00" & Month(Now), 2) & "/" & Right("00" & Day(Now), 2) & " " & Time
objOutFile.WriteLine today + " - " + pMessage

End Sub


Il suffit ensuite de l'appeler comme ceci:
Log "Application start"

Ce qui donne dans le fichier de logs:
2009/11/09 13:52:50 - Application start
[ Ajouter un commentaire ] ( ( 35 vues ) ) Lien permanent ( 3 / 230 )
Java: obtenir le document xml contenu dans un fichier docx 

Les fichiers docx contiennent un fichier xml, mais ce fichier xml est zippé dans le docx. Voici la procédure permettant d'obtenir le document xml (trouvé sur http://www.maxstocker.com/blog.php?en=c ... 9b3b863773):

/* Returns XML Document from a docx file
public Document getDocument(String File) throws Exception {
ZipFile docxfile = null;
try{
docxfile = new ZipFile(File);
}catch(Exception e){
// file corrupt or otherwise could not be found
throw new Exception("File is corrupted or is not a docx file.");
}
InputStream in = null;
try{
ZipEntry ze =
docxfile.getEntry("word/document.xml");
in = docxfile.getInputStream(ze);
}catch(NullPointerException nulle){
System.err.println("Expected entry word/document.xml does not exist");
throw new Exception("Expected entry word/document.xml does not exist");
}catch(Exception e){
throw new Exception("Error when trying to unzip the docx: " + e.getMessage());
}
Document document = null;
try{
DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
DocumentBuilder builder =
factory.newDocumentBuilder();
document = builder.parse(in);
}catch(ParserConfigurationException pce){
throw new Exception("ParserConfigurationException: " + pce.getMessage());
}catch(SAXException sex){
throw new Exception("SAXException: " + sex.getMessage());
}catch(IOException ioe){
throw new Exception("IOException: " + ioe.getMessage());
}finally{
try{
docxfile.close();
}catch(IOException ioe){
System.err.println("Exception closing file.");
throw new Exception("Unable to close the file (IOIOException): " + ioe.getMessage());
}
}

return document;

}
[ Ajouter un commentaire ] ( ( 37 vues ) ) Lien permanent ( 3 / 225 )
Vérifier la validité d'une adresse email 

J'ai trouvé sur Internet deux méthodes permettant de vérifier la validité d'une adresse email: une avec du PL/SQL et une autre en utilisant les expressions régulières.

Voici le code PL/SQL un peut modifié de http://www.developpez.net/forums/d60617 ... ite-email/

CREATE OR REPLACE FUNCTION INT_CODA.check_email(pUserName IN VARCHAR2)
RETURN boolean IS
l_dot_pos NUMBER;
l_at_pos NUMBER;
l_str_length NUMBER;
BEGIN
if pUserName is null or length(trim(pUsername)) = 0 then RETURN false; end if;
if instr(pUserName,'@.') > 0 then RETURN false; end if;

l_dot_pos := instr(pUserName
,'.');
l_at_pos := instr(pUserName
,'@');
l_str_length := length(pUserName);
IF ((l_dot_pos = 0) OR (l_at_pos = 0) OR (l_dot_pos = l_at_pos + 1) OR
(l_at_pos = 1) OR (l_at_pos = l_str_length) OR
(l_dot_pos = l_str_length))
THEN
RETURN false;
END IF;
IF instr(substr(pUserName
,l_at_pos)
,'.') = 0
THEN
RETURN false;
END IF;
RETURN true;
END check_email;
/


Voici une méthode utilisant les expressions régulières trouvée sur http://www.regular-expressions.info/email.html:
select REGEXP_INSTR('sebastien.thonnard@.com', '\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\')
from dual


... Si le résultat de la requête est 0, l'adresse email est mauvaise.


[ Ajouter un commentaire ] ( ( 36 vues ) ) Lien permanent ( 3 / 230 )
SAS: Ajouter une colonne qui est la somme d'une expression arythmétique 

Vous avez un dataset avec une colonne contenant une expression arithmétique. L'objectif retenu ici est de créer un nouveau dataset avec une colonne contenant la somme de l'expression arithmétique:



En prenant en compte le fait que le dataset à gauche se nomme test, on peut créer le dataset test2 avec le code suivant:


%let tmp = 0;
data test2;
set test;
call symput('tmp',seat);
call execute ('%let tmp = %eval(&tmp);');
total = symget('tmp');
run;

[ Ajouter un commentaire ] ( ( 44 vues ) ) Lien permanent ( 3 / 225 )

| 1 | 2 | 3 | 4 | 5 | 6 | Suivant> >>