SQl Server variable type text , ntext - SQL/NoSQL - Programmation
Marsh Posté le 11-07-2005 à 14:42:02
hmpf, ça me semble pas gagné en effet...
faudra que je regarde s'il y a une solution, à l'occasion. là j'ai pas le temps
Marsh Posté le 11-07-2005 à 15:15:30
Pffff...
A première vue, ça a l'air simple, mais quand on essaie de faire de façon automatisée, ça se complique...
Regarde à partie de là (aide de SQL Server)
Notes
Les fonctions et instructions suivantes peuvent être utilisées avec des données de type NText, text ou image.
Fonctions Instructions
DATALENGTH READTEXT
PATINDEX SET TEXTSIZE
SUBSTRING UPDATETEXT
TEXTPTR WRITETEXT
TEXTVALID
Seul souci, c'est que le READTEXT ne semble pas permettre d'écrire dans une variable.
Deplus, UPDATETEXT ne permet pas de faire une sous-requête à la place de la constante attendue.
A partir de là, je n'arrive pas à faire la concaténation directement à partir des données de la base
Marsh Posté le 11-07-2005 à 15:24:02
En gros, au final, ça devrait ressembler à ça, mais je suis bloqué au niveau du READTEXT qui ne veux pas se mettre dans une variable...
Code :
|
Marsh Posté le 11-07-2005 à 15:31:42
Groumpf !
Essaie de comprendre cette usine à gaz, je te laisse comprendre pourquoi les énormités qui sont dedans... Et surtout, je te laisse te prendre la tête pour tout optimiser, parceque là ça fait peur
Code :
|
En tout cas, CA MARCHE !!!!
Code :
|
Marsh Posté le 12-07-2005 à 15:58:56
Merci à toi Arjuna,
j'ai lu et je vais peux être me servir de ta solution si mes tests exploses pour l'instant je te donne la solution que j'ai trouvé. (Text, NTEXT et IMAGe c'est de la merde en barre, la plupart des fonctions ont un buffer limiter et n'accepte pas ces types)
j'ai trouvé une solution qui me permet de réussir la concaténation.
J'ai lu la documentation SQlServer à ce sujet juste après avoir trouvé une solution.
Il faut que je te dise l'ensemble de mon projet.
Je dois créer un fichier Xml qui se compos d'une partie fixe:
Partie 1
--------
<releve>
<.....>
Blabla
</.....>
</releve>
et l'autre variable:
Partie2
-------
<convive>
<enfant1>
<....>
</....>
<enfant1>
<enfant2>
<....>
</....>
<enfant2>
</convive>
Je récupère ces 2 parties à partir d'un FOR XML EXPLIT, donc je ne peux pas prédire le nombre caractères en sortie mais je sais que je vais dépassé les 8000.
Le but de la concaténation était d'obtenir :
<releve>
<enfant1>
<....>
</....>
<enfant1>
<enfant2>
<....>
</....>
<enfant2>
</convive>
<.....>
Blabla
</.....>
</releve>
Donc ce que j'ai fait c'est que j'ai coup' grâce à la fonction LEFT la partie fixe en 2.
J'ai fait un INSERT-SELECT de la partie Partie 2 et je fais un insert à nouveau de la fin de la partie 1.
Ca marche à condition que la partie 1 ne dépasse pas 16000 caractères. Le souci c'est que c'est un bordel car les variables de type text sont stocké sur plusieurs lignes.
@+
Marsh Posté le 12-07-2005 à 16:32:06
Hmmm... Ca reste pas très clair pour moi
En gros... Tu as une "partie 2" générée à partir de :
select ... from ... where ... for xml auto
OK, jusque là, pas de problème.
Le résultat, tu le récupères comment ? Tu le met où ?
Ensuite, ta "partie 1", elle vient d'où ? C'est fixe dans ton programme ? Stocké dans une table ? Récupéré comme "partie 2" ?
En tout cas, j'ai bien envie de jouer un peu avec ce problème là, ça peut toujours servir
PS: Sinon, truc sympa...
Tu sais qu'avec une PS SQL Server, tu peux instancier une DLL et jouer avec ?
Du coup, tu pourrais sans problème instancier un objet DOM, faire tes bidouilles avec à coup de AddNode(), puis enrefisrter le résultat final à l'aide de la propriété .text
Marsh Posté le 13-07-2005 à 14:04:36
Je vais essayer d'éclaircir au mieux.
J'utilise FOR XML EXPLICIT pour récupérer les informations de la base de données et former mon fichier XML.
Le résultat est une string en sortie.
J'utilise FOR XML EXPLICIT 2 fois (Tous se fait dans une seule procédure).
Le problème c'est que le select affiche le résultat mais celui-ci est stocké nulle part.
J'utilise OPENROWSET qui me renvoit le résultat de mon select que je veux stocker dans une variable.
Le problème c'est que le résultat renvoyé dépasse la capacité de la mémoire virtuel 8000.
Donc j'utilise une variable TEXT qui ne peut être que défini dans une table.
Je fais:
CREATE TABLE TEMP(
cle INT IDENTITY,
partie1 TEXT
)
INSERT INTO TEMP(partie1)(SELECT OP)
OP : OP est la string renvoyé par OPENROWSET
Arjuna: Le résultat, tu le récupères comment ? Tu le mets où ?
Là le résultat est directement dans ma table TEMP, voila une partie du code
Code :
insert into TEMP (partie1)
SELECT a.[XML_F52E2B61-18A1-11d1-B105-00805F49916B]
FROM OPENROWSET('MSDASQL',
'DRIVER={SQL Server};
SERVER=SI-REG-ETUDES\SQL_AGORA;UID=agora;PWD=agora',
'SELECT 1 AS Tag,
NULL AS Parent,
NULL AS [racine!1!]
.....
UNION
SELECT 2 AS
....
FOR XML EXPLICIT')as a
La j'ai récupérer ma partie 1, la partie 2 je la récupére de la même manière que la partie 1.
Maintenant je les concatènes:
j'ai 2 tables avec chacune une string de plus de 800 caractères.
TABLE 1: Le drapeau de couleur est suspendu en haut de l'immeuble
TABLE 2: rouge, vert, bleu
La table 2 peux grandir en fonction des éléments dans la base de données, je peux avoir juste rouge
je veux au final : Le drapeau de couleur rouge, vert, bleu est suspendu en haut de l'immeuble
Donc il faut utiliser la commande LEFT (SQL) qui va récupérer: Le drapeau de couleur
La commande RIGHT va récupérer : est suspendu en haut de l'immeuble
DAns une table final qui contiendra le résultat final je stocke la partie LEFT et j'insère les éléments de la table 2 puis j'insère la partie RIGHT.
Il faut se méfier LEFT et RIGHT, car il ne fonction pas sur des variable de type TEXT sans astuce
et le résultat est directement dans la table.
Au final la commande bcp me permet de mettre le résultat dans un fichier.
Voila, si tu as des questions no problem
@+
Marsh Posté le 13-07-2005 à 15:34:22
OK, je regarde ça
Sinon, tu viens de me faire découvrir "openrowset()", comment c'est trop terrible ce truc !
Code :
|
Et hop ! Je fais une jointure entre une table SQL Server, une table Access et une page Excel
Marsh Posté le 13-07-2005 à 16:01:10
Bon, ben ça fait grossomodo ce que tu veux
Code :
|
Sortie :
Code :
|
Marsh Posté le 14-07-2005 à 00:40:11
Oui j'arrive à obtenir le même résultat que toi pour optimiser tu peux mettre ta table #prout
en autoincrement comme ça à l'insertion tu ne te soucie plus de l'id.
Tu utilise un pointeur de TEXT, moi non car lorsque tu mets des variables de plus de 8000 dans une base de donnée par défaut, il te met 2033 caractères
sur la première ligne avec 1 comme repère et les restes tous les 2033.
Donc tu as :
#prout
______
id chaine
1 blablaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa jusqu'à 2033
2 blablaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa jusqu'à 2033
etc.
Donc je fais un WHILE avec une recherche du mot couleur dès que je le trouve je casse la boucle
et je retiens l'indice de boucle.
Dans mon texte je sais que le mot je vais le touvé sur la première ligne mais on sait jamais donc c'est un test qui normalement va s'arrêter
sur la première ligne.
L'auto incrément t'evite la numérotation
J'avoue que tes variables me déstabilise mais tu fais 3 insert pour les couleurs alors que c'est une string qui contient les 3 mots.
Losrque tu fais SELECT COULEUR FROM tableCouleur tu obtiens
'Rouge, Vert' par exemple donc un select suffit
Voila du code:
@v_nbCaractere : nombre de caractères de la partie gauche
-- Partie Gauche
INSERT INTO table3(phraseFinale) SELECT LEFT(CONVERT(VARCHAR(8000), partie1), @v_nbCaractere-1) AS Gauche
FROM TABLE1
WHERE idpartie1 = 1 (a optimiser)
--Partie 2
INSERT INTO table3(phraseFinale) SELECT partie2 FROM ..partie2
Cette partie peut faire 1600 caractères je ne vais jamais la SET
-- 2033 est la taille maximal d'une ligne
-- Le debut de la partie de gauche tient sur la première ligne
SET @v_fin = (2033-@v_nbCaractere+1)
--Partie Droite
SELECT RIGHT(CONVERT(VARCHAR(8000), partie1),@v_fin)AS Droite
FROM TABLE1
INSERT INTO table3(phraseFinale) SELECT RIGHT(CONVERT(VARCHAR(8000), partie1),@v_fin)AS Droite
FROM TABLE1
SELECT phraseFinale FROM table3
Je veux juste ajouter que tu dois te méfier de OPENROWSET() car c'est pas pratique lorsque tu mets un long select dans ta query,
si il y a un bug il ne te dira pas où.
Comme la query est une string pas question de faire un Where ID = @variable dedans, il n'accepte pas
L'astuce que j'ai trouvé est de mettre @variable dans une table.
Attention OPENROWSET() n'accepte pas les select sur mes tables temporaires
Pour les varibles text la plupart des trucs que tu peux faire sur des varchar ne sont pas accepter
Marsh Posté le 14-07-2005 à 00:51:40
pour le openrowset(), je ne tiens pas à l'utiliser pour faire des requêtes de SQL Server à SQL Server : il y a déjà tout ce qu'il faut de base.
mais pour aller lire dans des autres bases hétéroclites, ça rox carrément.
sinon, une solution simple au "where id = @id" c'est de faire :
set @query = 'select truc from latable where id = ' + @id
et d'utiliser ensuite la variable @query
Marsh Posté le 14-07-2005 à 01:01:30
en fait, le openrowset semble super utile dans des cas spécifiques du genre :
-> j'ai un PABX qui s'interface avec un soft. Ce dernier sort des logs au format CSV sous la forme :
numéro_de_téléphone;poste_interne;durée
Chaque fichier CSV correspond à une journée. Il peut faire mettons 10 000 lignes.
Afin de ne pas surcharger inutilement la base, parceque je ne m'en sers pas tous les jours, je préfère garder les logs sous ce format, plutôt que recopier dans la base de données.
Par contre, lorsqu'une personne du call center reçoit un numéro de téléphone, je dois lui afficher le nombre de fois que ce numéro a déjà appelé, et quels sont les agents qui ont répondu, et ce, sur 7 jours d'historique.
Ainsi, je peux faire :
Code :
|
=> Ca, franchement, c'est terrible !
Marsh Posté le 14-07-2005 à 11:42:16
Bonjour,
je ne sais pas encore ce qu'est un PABX qui s'interface avec un soft.
Et quel est la particularité du format CSV.
J'ai bien saisi que tu veux garder les logs en mettant les résultats du SELECT dans un fichier LOG sous c:\logs\
C'est de la balle comme ca tu évite de surcharger la base de données.J'ai pas compris comment tu sauvergardetes données dans ton dossier log et est-ce que OPENROWSET() te renvoie bien une table.
Cette partie tu va s devoir me l'expliquer:
Par contre, lorsqu'une personne du call center reçoit un numéro de téléphone, je dois lui afficher le nombre de fois que ce numéro a déjà appelé, et quels sont les agents qui ont répondu, et ce, sur 7 jours d'historique.
Marsh Posté le 18-07-2005 à 00:17:43
-> un PABX, c'est un équipement téléphonique, un standard sans hôtesse si tu préfères : X postes sont reliés à un seul numéro de téléphone externe, et ce dernier s'occupe de relayer plusieurs appels simultanés de la même ligne sur des postes différents. ils disposent la plupart du temps d'une interface RS232 qui permet de suivre en temps réel, sur un ordinateur, l'activité des appels.
=> dans le cas que je donne en exemple, le PABX est relié à un serveur, dont le drivers écrit simplement des logs au fichier CSV au fur et à mesure des appels.
Le CSV n'a rien de particulier, pas plus que le TSV, les fichiers à pas fixe, ou n'importe quel autre format de transfert (XML, etc.) Il est seulement le plus répendu, donc le plus probable. Il se traduit par un fichier texte formatté en colonnes, dont les valeurs sont séparées par des virgules (CSV = Coma Separated Values), et donc très facile à lire, sans perte de place contrairement au XML ou les fichiers à pas fixe.
Esuite, dans mon exemple, plutôt que d'attendre la fin de la journée que le log soit terminé, pour le recopier dans une base de données, je veux pouvoir faire des statistiques "en temps réel" sur ses données, tout en les liant à des données de ma base.
OpenRowSet retourne sous la forme d'une table temporaire le résultat d'une requête de type sélection, se basant non pas sur une table de SQL Server, mais un lien OLE DB, c'est à dire que depuis une requête SQL Server, on peut faire une requête portant sur des tables de différents SGBD, ou directement lire certains formats courants, tels que le CSV, le format Excel ou autres.
Donc dans mon exemple, si je veux récupérer des informations du PABX portant sur les 7 derniers jours, je fais simplement un gros UNION portant sur des OPENROWSET qui ouvre les logs des 7 derniers jours.
Marsh Posté le 09-07-2005 à 00:33:18
Bonjour tous le monde,
je vous soumet un petit problème SQl, que je rencontre actuellement.
J'ai une variable de type text qui doit recevoir une phrase assez longue.
Je n'ai pas utiliser de VARCHAR(80000) car je les dépasse largement.
Le problème du type text c'est qu'on ne peut pas les définr en global.
Il faut définir la variable dans une table comme :
CREATE TABLE TABLEAU(
chaine TEXT
)
CREATE TABLE2 TABLEAU(
chaine2 TEXT
)
Le souci c'est que j'ai besoin de concatener 2 chaines et je crois qu'il est impossible de 'SETter' ce type (trop grand)
Ce que je veux si je n'ai pas été assez claire.
SET chaine = 'a'
SET chaine2 = 'b'
Je veux obtenir 'ab'
Merci