web-dev-qa-db-fra.com

Pad droit une chaîne avec un nombre variable d'espaces

J'ai une table de client que je veux utiliser pour remplir une zone de paramètre dans SSRS 2008. Le cust_num est la valeur et la concaténation du cust_name et du cust_addr sera l'étiquette. Les champs obligatoires de la table sont:

cust_num     int            PK
cust_name    char(50)       not null
cust_addr    char(50)

Le SQL est:

select cust_num, cust_name + isnull(cust_addr, '') address
from customers

Ce qui me donne ceci dans la liste des paramètres:

FIRST OUTPUT - ACTUAL
1       cust1              addr1
2       customer2               addr2

C'est ce à quoi je m'attendais mais je veux:

SECOND OUTPUT - DESIRED
1       cust1              addr1
2       customer2          addr2

Ce que j'ai essayé

select cust_num, rtrim(cust_name) + space(60 - len(cust_name)) +
                 rtrim(cust_addr) + space(60 - len(cust_addr)) customer
from customers

Ce qui me donne la première sortie.

select cust_num, rtrim(cust_name) + replicate(char(32), 60 - len(cust_name)) +
                 rtrim(cust_addr) + replicate(char(32), 60 - len(cust_addr)) customer

Ce qui me donne aussi la première sortie.

J'ai également essayé de remplacer space() par char(32) et vice versa

J'ai essayé des variantes de substring, left, right en vain.

J'ai également utilisé ltrim et rtrim à divers endroits.

La raison du 60 est que j’ai vérifié la longueur maximale dans les deux champs. C’est 50 et je veux de l’espace entre les champs même si le champ est au maximum. Je ne suis pas vraiment préoccupé par les données tronquées car la ville, l'état et le zip sont dans des champs différents. Par conséquent, si l'adresse de fin de rue est coupée, tout va bien, je suppose.

Ce n'est pas un spectacle, le rapport SSRS est actuellement déployé avec la première sortie, mais j'aimerais le rendre plus propre si je le peux.

23
Tony

Whammo blammo (pour les espaces principaux):

SELECT 
    RIGHT(space(60) + cust_name, 60),
    RIGHT(space(60) + cust_address, 60)

OU (pour les espaces de fin)

SELECT
    LEFT(cust_name + space(60), 60),
    LEFT(cust_address + space(60), 60),
62
Jim

Ceci est basé sur la réponse de Jim,

SELECT
    @field_text + SPACE(@pad_length - LEN(@field_text)) AS RightPad
   ,SPACE(@pad_length - LEN(@field_text)) + @field_text AS LeftPad

Avantages 

  • Plus simple
  • Légèrement plus propre (IMO)
  • Plus rapide (peut-être?)
  • Facilement modifié pour un double pavé pour l'affichage dans des polices de largeur non fixe ou un rembourrage divisé à gauche et à droite au centre 

Désavantages

  • Ne gère pas LEN (@field_text)> @pad_length 
3
KMier

Le moyen le plus simple de placer à droite une chaîne avec des espaces (sans les rogner) est simplement de la convertir en CHAR (longueur). MSSQL supprimera parfois les espaces de VARCHAR (car il s’agit d’un type de données de longueur variable). Dans la mesure où CHAR est un type de données de longueur fixe, SQL Server ne coupera jamais les espaces de fin et complétera automatiquement les chaînes plus courtes que sa longueur par des espaces. Essayez l'extrait de code suivant, par exemple.

SELECT CAST('Test' AS CHAR(20))

Ceci retourne la valeur 'Test '.

2
Justin C

Basé sur la réponse de KMier , répond que cette méthode pose un problème lorsque le champ à remplir n'est pas un champ mais le résultat d'une fonction (éventuellement compliquée); toute la fonction doit être répétée.

Cela permet également de remplir un champ avec la longueur maximale de son contenu.

WITH
cte AS (
  SELECT 'foo' AS value_to_be_padded
  UNION SELECT 'foobar'
),
cte_max AS (
  SELECT MAX(LEN(value_to_be_padded)) AS max_len
)
SELECT
  CONCAT(SPACE(max_len - LEN(value_to_be_padded)), value_to_be_padded AS left_padded,
  CONCAT(value_to_be_padded, SPACE(max_len - LEN(value_to_be_padded)) AS right_padded;
0
SQB