TSQL d'erreur lors de l'insertion de chaînes de caractères ou des données binaires seront tronquées”
Dans le code ci-dessous je suis insertion de valeurs dans un tableau et d'obtenir l'erreur "de la Chaîne ou des données binaires d'être tronquée."
Ma définition de la table:
CREATE TABLE urs_prem_feed_out_control
(
bd_pr_cntl_rec_type char(7) NULL ,
pd_pr_cntl_acctg_dte char(6) NULL ,
bd_pr_cntl_run_dte char(10) NULL ,
bd_pr_cntl_start_dte char(10) NULL ,
bd_pr_cntl_end_dte char(10) NULL ,
bd_pr_cntl_rec_count char(16) NULL ,
bd_pr_tot_premium char(16) NULL ,
bd_pr_tot_commission char(16) NULL ,
fd_ctl_nbr integer NOT NULL
)
DECLARE @cur_fd_ctl_nbr INT = 2,
@acctg_cyc_ym_2 CHAR(6) = '201402',
@rundate CHAR (10) = CONVERT(CHAR(10),GETDATE(),101),
@cycle_start_dt DATETIME = '2014-02-17',
@cycle_end_dt DATETIME = '2014-02-24',
@record_count INT = 24704,
@tot_pr_premium DECIMAL(18,2) = 476922242,
@tot_pr_comm DECIMAL(18,2) = 2624209257
Insérer le code (je l'ai déclaré les variables comme des constantes les valeurs pour le test, j'ai pris ces valeurs à partir de ce qu'ils étaient au moment de l'exécution):
INSERT INTO urs_prem_feed_out_control
SELECT fd_ctl_nbr = @cur_fd_ctl_nbr,
bd_pr_cntl_rec_type = 'CONTROL',
bd_pr_cntl_acctg_dte = @acctg_cyc_ym_2,
bd_pr_cntl_run_dte = @rundate,
bd_pr_cntl_start_dte = CONVERT(CHAR(10),@cycle_start_dt,101),
bd_pr_cntl_end_dte = CONVERT(CHAR(10),@cycle_end_dt,101),
bd_pr_cntl_rec_count = RIGHT('0000000000000000' + RTRIM(CONVERT(CHAR(16),@record_count)),16),
bd_pr_tot_premium = CASE
WHEN @tot_pr_premium < 0
THEN '-' + SUBSTRING(RIGHT('000000000000000' + LTRIM(RTRIM(CONVERT(VARCHAR,ABS(@tot_pr_premium)*100))),18),1,15)
ELSE
'+' + SUBSTRING(RIGHT('000000000000000' + LTRIM(RTRIM(CONVERT(VARCHAR,ABS(@tot_pr_premium)*100))),18),1,15)
END,
bd_pr_tot_commission = CASE
WHEN @tot_pr_comm < 0
THEN '-' + SUBSTRING(RIGHT('000000000000000' + LTRIM(RTRIM(CONVERT(VARCHAR,ABS(@tot_pr_comm)*100))),18),1,15)
ELSE
'+' + SUBSTRING(RIGHT('000000000000000' + LTRIM(RTRIM(CONVERT(VARCHAR,ABS(@tot_pr_comm)*100))),18),1,15)
END
Quand je regarde chaque valeur individuellement, il semble qu'ils sont tous à l'intérieur de la longueur variable des contraintes de la table. Aucune idée de pourquoi j'obtiens cette erreur?
Merci!
Eh bien, au moins un est trop long sinon vous ne seriez pas obtenir cette erreur. Essayez de remplacer une variable à la fois, par exemple avec un
Écrire un select avec tous les len().
Réécriture de l'instruction INSERT pour un SELECT avec tous les len ()'. Obtenu 7,6,10,10,10,16,16,16 qui correspond exactement à la colonne longueurs. Quand je reviens à l'INSERTION-je obtenir la "Chaîne de caractères ou des données binaires seront tronquées" erreur!!!
Pourquoi êtes-vous en mélange de style 101 (
Oui, je sais, mais quand je vois toutes ces mauvaises choses, je dois parler d'eux, trop.
NULL
valeur ou un caractère unique (par exemple,*
) - lorsque l'erreur disparaît, vous avez vos délinquance de la valeur de la colonne!Écrire un select avec tous les len().
Réécriture de l'instruction INSERT pour un SELECT avec tous les len ()'. Obtenu 7,6,10,10,10,16,16,16 qui correspond exactement à la colonne longueurs. Quand je reviens à l'INSERTION-je obtenir la "Chaîne de caractères ou des données binaires seront tronquées" erreur!!!
Pourquoi êtes-vous en mélange de style 101 (
mm/dd/yyyy
) et le style de 120 (yyyy-mm-dd
) au lieu de à l'aide d'un absolument sans équivoque format comme yyyymmdd
? Pourquoi êtes-vous la conversion de varchar
sans longueur? Et pourquoi n'êtes-vous pas la liste des noms de colonnes dans votre instruction insert? Avis de la colonne qui est dernier dans votre table, mais premier dans votre liste de sélection. </facepalm>Oui, je sais, mais quand je vois toutes ces mauvaises choses, je dois parler d'eux, trop.
OriginalL'auteur intA | 2014-06-23
Vous devez vous connecter pour publier un commentaire.
Le problème avec votre requête d'insertion est L'ORDRE D'INSERTION :
Cette colonne doit être définie lors de la dernière dans le
INSERT
comme la dernière colonne définie dans le script de table créer.Modifier votre requête:
Faire ce serait aussi travailler. Notez que la première colonne, ici, dans le
SELECT
dans leINSERT
est juste la façon dont vous avez fourni dans votre question.Voir ici-> http://sqlfiddle.com/#!3/0e09b/1
Espérons que cette aide!!!
Voir la deuxième partie de la réponse, où les noms de colonnes sont spécifiées. Il y a un violon pour que, trop (Voir la tripoter près de la fin de la réponse).
Il n'y a pas besoin de modifier la réponse. Deux les moyens de FAIRE le travail. C'est seulement une question de "meilleures pratiques" . Cependant, personnellement, je ne préférez les & recommander en spécifiant les noms de colonne.
Ce n'est pas une question de bonnes pratiques, il est question de promouvoir les mauvaises pratiques surtout depuis que les mauvaises pratiques (qui a été la cause de son problème) qui est venu en premier. J'ai considéré downvoting vous au lieu de cela mais élu à modifier puisque vous avez la bonne solution. Mais l'OP besoin de voir que la deuxième solution est ce qu'il devrait ne pas utiliser le premier ou à, cela cassera la prochaine fois qu'il met les colonnes de l'ordre.
La raison pour laquelle vous voyez la "bonne solution" est parce que c'est ce que j'utilise personnellement et je suis à l'aise avec. J'ai effectivement eu à modifier ce que sur mon poste de travail pour arriver à la un avec aucun des noms de colonne. Mais oui, je suis d'accord, je l'ai mentionné que dans ma réponse que ce n'est pas la "bonne" façon d'aller de l'avant. Et sur une autre note, il y a beaucoup de choses qui ne vont pas avec la façon dont la requête est encadrée (Aaron Bertrand jette quelque lumière sur ce point dans ses commentaires).
OriginalL'auteur Satwik Nadkarny
C'est pourquoi vous devriez ne jamais écrire une instruction insert sans spécifier les colonnes. Puisque vous n'avez pas, elle sera d'essayer de mettre les données dans les colonnes dans l'ordre où ils sont présentés dans le tableau qui n'est pas du tout l'ordre que vous les avez dans les.
Une autre chose qui peut vous arriver quand vous recevez ce genre de message (mais que je ne pense pas que s'applique dans votre cas, je l'inclus pour les personnes à la recherche plus tard), c'est que le eeror provient réellement d'un déclencheur et pas la principale insérer.
Enfin une remarque sur la conception de base de données, vous ne devriez pas utiliser char pour les dates, vous devriez être en utilisant les champs de date. Vous ne pouvez pas faire la date de calcul sur un champ char et il va accepter de date incorrect des valeurs comme feb30, 2014. C'est toujours une mauvaise idée de stocker des dates que rien, sauf la date ou datetime. En général char ne devraient être utilisées que rarement, lorsqu'une colonne aura toujours le même nombre de caractères (comme une colonne 2 état de l'abréviation), il ne devrait pas être utilisée comme type de données par défaut. Vous avez besoin de faire un meilleur travail de définition de types de données qui correspondent au type et à la taille des données stockées. Vous pouvez rencontrer des problèmes avec des requêtes comme " VA " n'est pas la même chose que 'VA '. En général, mon expérience est que moins de 1 % de tous les champs de base de données doit être de type Char.
OriginalL'auteur HLGEM
Je pense qu'il peut être bénéfique pour vérifier votre travail. Considérons l'exemple de code suivant:
Toutes les rendements suivants: Chaîne ou des données binaires d'être tronquée.
OriginalL'auteur Rawle