1
votes

Comment extraire tous les 7 caractères d'un nvarchar dans une autre table?

J'ai un nvarchar (200) appelé ColumnA dans Table1 qui contient, par exemple, la valeur:

ABCDEFG
BCDEFGH
CDEFGHI
DEFGHIJ
EFGHIJK
FGHIJKL
GHIJKLM
HIJKLMN
IJKLMNO
JKLMNOP
KLMNOPQ
LMNOPQR
MNOPQRS
NOPQRST
OPQRSTU
PQRSTUV
QRSTUVW
RSTUVWX
STUVWXY
TUVWXYZ

Je veux extraire tous les 7 caractères dans Table2, ColumnB et finir avec tous de ces valeurs ci-dessous.

ABCDEFGHIJKLMNOPQRSTUVWXYZ

[Pas les vrais noms de table et de colonne.]

Les données sont en cours de chargement dans Table1 et Table2 dans un package SSIS, et je me demande s'il est préférable de gérer la chaîne dans TSQL dans une tâche SQL ou d'analyser la chaîne dans un composant de script VB.

[Oui, je pense que nous sommes les quatre derniers de la planète à utiliser VB dans les composants de script. Je ne peux pas convaincre les trois autres que ce truc C # est là pour rester. Cependant, c'est peut-être le moment idéal pour devenir voyou.]


0 commentaires

4 Réponses :


0
votes

Vous pouvez le faire avec T-SQL comme ceci:

DECLARE C CURSOR LOCAL FOR SELECT [ColumnA] FROM [Table1]
OPEN C

DECLARE @Val nvarchar(200);
FETCH NEXT FROM C into @Val
WHILE @@FETCH_STATUS = 0 BEGIN
    DECLARE @I INTEGER;
    SELECT @I = 1;
    WHILE @I <= LEN(@vAL)-6 BEGIN
        PRINT SUBSTRING(@Val, @I, 7)
        SELECT @I = @I + 1
    END
    FETCH NEXT FROM C into @Val
END
CLOSE C


1 commentaires

CURSOR a été introduit par le diable de la pensée procédurale pour nous conduire les pauvres petits utilisateurs de bases de données dans le noir et le mal. Entrez dans la lumière de la réflexion basée sur les ensembles et évitez les fonctions CURSOR , WHILE et multi-instructions à chaque fois tu peux. :-)



2
votes

Vous pouvez utiliser un CTE récursif calculant les décalages pas à pas et substring().

WITH
cte
AS
(
SELECT 1 n
UNION ALL
SELECT n + 1 n
       FROM cte
       WHERE n + 1 <= len('ABCDEFGHIJKLMNOPQRSTUVWXYZ') - 7 + 1
)
SELECT substring('ABCDEFGHIJKLMNOPQRSTUVWXYZ', n, 7)
       FROM cte;

db violon


1 commentaires

J'aime cette approche, mais chaque fois que vous utilisez un CTE récursif pour créer un tally-on-the-fly , vous devez être conscient de la profondeur maximale de 100 qui peut nécessiter une OPTION MAXRECURSION < / code> sur la requête la plus externe chaque fois que vous utilisez ceci ... C'est pourquoi je recherche une table de nombres ou une solution via ROW_NUMBER par rapport à un ensemble plus grand (que vous pouvez CROISER) à n'importe quel nombre nécessaire. J'ai placé une réponse moi-même .... +1 de mon côté.



1
votes

Si vous avez une table de nombres physiques, c'est facile. Sinon, vous pouvez créer un tally-on-the-fly :

WITH Tally(Nmbr) AS
(SELECT TOP(LEN(@string)-6) ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) FROM master..spt_values)
SELECT Nmbr
      ,SUBSTRING(@string,Nmbr,7) AS FragmentOf7
FROM Tally
ORDER BY Nmbr;

- Nous créons le pointage en utilisant ROW_NUMBER contre tout table avec suffisamment de lignes.

DECLARE @string VARCHAR(100)='ABCDEFGHIJKLMNOPQRSTUVWXYZ';

L'idée en bref: Le décompte renvoie une liste de nombres de 1 à n (n = LEN (@string) -6). Ce numéro est utilisé dans SUBSTRING pour définir la position de départ.


0 commentaires

0
votes

Solution du composant de script

En supposant que le nom de la colonne d'entrée est Column1

  1. Ajouter un composant de script
  2. Ouvrez le formulaire de configuration du composant de script
  3. Accédez à l'onglet Entrées et sorties
  4. Cliquez sur l'icône Sortie et définissez la propriété Synchronous Input sur Aucun
  5. Ajouter une colonne de sortie (exemple outColumn1)
  6. Dans l'éditeur de script, utilisez un code similaire dans la fonction de traitement des lignes:
Dim idx as integer = 0

While Row.Column1.length > idx + 7

    Output0Buffer.AddRow()
    Output0Buffer.outColumn1 = Row. 
    Column1.Substring(idx,7)

    idx +=1

End While


0 commentaires