Erreur TSQL lors de l'insertion "Les données string ou binarys sont tronquées"

Dans le code ci-dessous, j'insère des valeurs dans une table et j'obtiens l'erreur "Les données string ou binary seraient tronquées".

Ma définition de 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 du code (j'ai déclaré les variables comme valeurs constantes pour le test, j'ai pris ces valeurs de ce qu'elles étaient à 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 soient tous dans les limites de longueur variable de la table. Une idée de pourquoi je reçois cette erreur?

Merci!

Le problème avec votre requête d'insertion est L'ORDRE D'INSERTION :

 SELECT fd_ctl_nbr = @cur_fd_ctl_nbr, 

Cette colonne doit être définie au dernier dans l' INSERT comme étant la dernière colonne définie dans le script de création de table.

Changez votre requête en ceci:

  INSERT INTO #urs_prem_feed_out_control (fd_ctl_nbr, bd_pr_cntl_rec_type, pd_pr_cntl_acctg_dte, bd_pr_cntl_run_dte, bd_pr_cntl_start_dte, bd_pr_cntl_end_dte, bd_pr_cntl_rec_count, bd_pr_tot_premium, bd_pr_tot_commission) 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 

Faire cela fonctionnerait aussi. Notez que la première colonne ici dans le SELECT dans l' INSERT est juste la façon dont vous avez fourni dans votre question.

Voir ceci ici-> http://sqlfiddle.com/#!3/0e09b/1

J'espère que cela t'aides!!!

C'est pourquoi vous ne devriez jamais écrire une instruction d'insertion sans spécifier les colonnes. Comme vous ne l'avez pas fait, il essaiera de placer datatables dans les colonnes dans l'ordre où elles se trouvent dans la table, ce qui n'est pas du tout l'ordre dans lequel elles se trouvent.

Une autre chose qui peut arriver quand vous recevez ce genre de message (mais je ne pense pas que cela s'applique dans votre cas, je l'inclue pour les personnes qui cherchent plus tard) est que l'eeror provient d'un sortinggger et non de l'insert principal.

Enfin, une note sur la design de la database, vous ne devriez pas utiliser char pour les dates, vous devriez utiliser des champs de date. Vous ne pouvez pas faire de maths de date sur un champ char et acceptera des valeurs de date incorrectes comme feb30, 2014. Il est toujours une mauvaise idée de stocker des dates, sauf les valeurs de date ou de date et heure. En général, un caractère ne devrait être utilisé que rarement lorsqu'une colonne aura toujours le même nombre de caractères (comme une abréviation d'état à deux colonnes), elle ne devrait pas être utilisée comme type de données par défaut. Vous devez mieux définir les types de données correspondant au type et à la taille des données stockées. Vous pouvez rencontrer des problèmes avec les requêtes car 'VA' n'est pas la même chose que 'VA'. En général, mon expérience est que less de 1% de tous les champs de la database devrait être Char.

Je pense qu'il peut être avantageux de vérifier votre travail. Considérez l'exemple de code suivant:

 DECLARE @Table TABLE (Name NVARCHAR(1)) INSERT INTO @Table (Name) SELECT 'ab' INSERT INTO @Table (Name) SELECT SUBSTRING('ab',1,2) INSERT INTO @Table (Name) SELECT RIGHT('abc',2) 

Tous donnent les résultats suivants: Les données string ou binary seraient tronquées.