errorোকানোর চেষ্টা করার সময় ত্রুটি, স্ট্রিং বা বাইনারি ডেটা কেটে যাবে


250

আমি নিম্নলিখিত লাইনের সাথে ডেটা.বাট ফাইল চালাচ্ছি:

Rem Tis batch file will populate tables

cd\program files\Microsoft SQL Server\MSSQL
osql -U sa -P Password -d MyBusiness -i c:\data.sql

ডেটা.এসকিউএল ফাইলের সামগ্রীগুলি হ'ল:

   insert Customers
            (CustomerID, CompanyName, Phone)
             Values('101','Southwinds','19126602729')

রেকর্ড যুক্ত করার জন্য আরও 8 টি অনুরূপ লাইন রয়েছে।

যখন আমি এই চালানো start> run> cmd> c:\data.batআমি এই ত্রুটি বার্তা পাবেন:

1>2>3>4>5>....<1 row affected>
Msg 8152, Level 16, State 4, Server SP1001, Line 1
string or binary data would be truncated.

<1 row affected>

<1 row affected>

<1 row affected>

<1 row affected>

<1 row affected>

<1 row affected>

এছাড়াও, আমি স্পষ্টতই একজন নবাগত, তবে কী Level #এবং এর state #অর্থ কী এবং আমি কীভাবে উপরের বার্তার মতো ত্রুটি বার্তাগুলি সন্ধান করব: 8152?

উত্তর:


609

থেকে @ gmmastros এর উত্তর

আপনি যখনই বার্তাটি দেখুন ...

স্ট্রিং বা বাইনারি তথ্য ছেঁটে ফেলা হবে

নিজেকে ভাবুন ... ক্ষেত্রটি আমার ডেটা ধরে রাখতে যথেষ্ট বড় নয়।

গ্রাহকদের টেবিলের জন্য টেবিলের কাঠামোটি পরীক্ষা করুন। আমি মনে করি আপনি সন্নিবেশ করানোর চেষ্টা করছেন এমন ডেটা ধরে রাখতে এক বা একাধিক ক্ষেত্রের দৈর্ঘ্য যথেষ্ট বড় নয়। উদাহরণস্বরূপ, যদি ফোন ক্ষেত্রটি একটি বার্চার (8) ক্ষেত্র হয় এবং আপনি এতে 11 টি অক্ষর রাখার চেষ্টা করেন তবে আপনি এই ত্রুটি পাবেন।


16
এছাড়াও মনে রাখবেন যে প্রভাবিত ক্ষেত্রগুলি একটি ট্রিগার হতে পারে। আশা করি পরের বার এটি হওয়ার পরে আমি এটি মনে রাখব ...
কেভিন পোপ

14
ডিবাগে দেখার কোন উপায় কি কোন ক্ষেত্রটি কেটে ফেলা হবে?
ডেইলিফ্র্যাঙ্কপিটার

এই ত্রুটিটি কারণ আপনার কলামটি আপনার স্থির দৈর্ঘ্যের পরে ডেটা ধরে রাখতে পারে না। যেমন; Firstname nvarchar(5) যদি আপনি 5 টিরও বেশি অক্ষর
প্রকাশ

26

ক্ষেত্রের দৈর্ঘ্যের চেয়ে ডেটা দৈর্ঘ্য ছোট ছিল যদিও আমার এই সমস্যা ছিল had দেখা গেল যে সমস্যাটিতে আরও একটি লগ টেবিল রয়েছে (নিরীক্ষণের পথের জন্য), মূল টেবিলে একটি ট্রিগার দ্বারা পূর্ণ, যেখানে কলামের আকারও পরিবর্তন করতে হয়েছিল।


1
ধন্যবাদ। খনিটি ছিল কারণ টেবিলএ-এর বর্গাকার কলামটি বারচর (100)। এটি অন্য টেবিলটিতেও সন্নিবেশ করায়, কলামটি ভারচর (50)।
Hnin Htet Htet অং

1
আমার ক্ষেত্রেও একই সমস্যা হয়েছিল। একটি ট্রিগার অপারেশন ছিল অপরাধী।
অটোপাইলট

19

INSERTবিবৃতিগুলির একটিতে আপনি একটি স্ট্রিং ( varcharবা nvarchar) কলামে খুব দীর্ঘ স্ট্রিং in োকানোর চেষ্টা করছেন ।

যদি এটি স্পষ্ট না হয় যা INSERTস্ক্রিপ্টটি স্রেফ দেখার দ্বারা অপরাধী, আপনি ত্রুটি বার্তার আগে<1 row affected> উপস্থিত রেখাগুলি গণনা করতে পারেন । প্রাপ্ত নম্বর প্লাস ওয়ান আপনাকে বিবৃতি নম্বর দেয়। আপনার ক্ষেত্রে এটি দ্বিতীয় INSERT বলে মনে হচ্ছে যা ত্রুটি তৈরি করে।


2
আমার একই সমস্যা হচ্ছে, কীভাবে কোন কলামটি ত্রুটি সৃষ্টি করছে তা সন্ধান করবেন?
সিটিয়া মাতোস

@ অ্যান্ড্রেস্টোস: সম্ভবত আপনি এটি একটি প্রশ্ন হিসাবে জমা দিতে পারেন (অন্য কেউ যদি ইতিমধ্যে এটি না করে থাকে, তবে এক্ষেত্রে কোথাও এর প্রস্তুত উত্তর থাকতে পারে)।
অ্যান্ড্রি এম

11

আপনার কিছু ডেটা আপনার ডাটাবেস কলামে (ছোট) ফিট করতে পারে না। ভুল কী তা খুঁজে পাওয়া সহজ নয়। আপনি যদি সি # এবং লিনক 2 এসকিউএল ব্যবহার করেন তবে আপনি সেই ক্ষেত্রটি তালিকাবদ্ধ করতে পারেন যা কেটে যাবে:

প্রথমে সহায়ক শ্রেণি তৈরি করুন:

public class SqlTruncationExceptionWithDetails : ArgumentOutOfRangeException
{
    public SqlTruncationExceptionWithDetails(System.Data.SqlClient.SqlException inner, DataContext context)
        : base(inner.Message + " " + GetSqlTruncationExceptionWithDetailsString(context))
    {
    }

    /// <summary>
    /// PArt of code from following link
    /// http://stackoverflow.com/questions/3666954/string-or-binary-data-would-be-truncated-linq-exception-cant-find-which-fiel
    /// </summary>
    /// <param name="context"></param>
    /// <returns></returns>
    static string GetSqlTruncationExceptionWithDetailsString(DataContext context)
    {
        StringBuilder sb = new StringBuilder();

        foreach (object update in context.GetChangeSet().Updates)
        {
            FindLongStrings(update, sb);
        }

        foreach (object insert in context.GetChangeSet().Inserts)
        {
            FindLongStrings(insert, sb);
        }
        return sb.ToString();
    }

    public static void FindLongStrings(object testObject, StringBuilder sb)
    {
        foreach (var propInfo in testObject.GetType().GetProperties())
        {
            foreach (System.Data.Linq.Mapping.ColumnAttribute attribute in propInfo.GetCustomAttributes(typeof(System.Data.Linq.Mapping.ColumnAttribute), true))
            {
                if (attribute.DbType.ToLower().Contains("varchar"))
                {
                    string dbType = attribute.DbType.ToLower();
                    int numberStartIndex = dbType.IndexOf("varchar(") + 8;
                    int numberEndIndex = dbType.IndexOf(")", numberStartIndex);
                    string lengthString = dbType.Substring(numberStartIndex, (numberEndIndex - numberStartIndex));
                    int maxLength = 0;
                    int.TryParse(lengthString, out maxLength);

                    string currentValue = (string)propInfo.GetValue(testObject, null);

                    if (!string.IsNullOrEmpty(currentValue) && maxLength != 0 && currentValue.Length > maxLength)
                    {
                        //string is too long
                        sb.AppendLine(testObject.GetType().Name + "." + propInfo.Name + " " + currentValue + " Max: " + maxLength);
                    }

                }
            }
        }
    }
}

তারপরে সাবমিজচেঞ্জের জন্য মোড়ক প্রস্তুত করুন:

public static class DataContextExtensions
{
    public static void SubmitChangesWithDetailException(this DataContext dataContext)
    {
        //http://stackoverflow.com/questions/3666954/string-or-binary-data-would-be-truncated-linq-exception-cant-find-which-fiel
        try
        {
            //this can failed on data truncation
            dataContext.SubmitChanges();
        }       
        catch (SqlException sqlException) //when (sqlException.Message == "String or binary data would be truncated.")
        {

            if (sqlException.Message == "String or binary data would be truncated.") //only for EN windows - if you are running different window language, invoke the sqlException.getMessage on thread with EN culture
                throw new SqlTruncationExceptionWithDetails(sqlException, dataContext);
            else
                throw;
        }
    }
}

গ্লোবাল ব্যতিক্রম হ্যান্ডলার এবং লগ কাট বিশদটি প্রস্তুত করুন:

protected void Application_Error(object sender, EventArgs e)
{
    Exception ex = Server.GetLastError();
    string message = ex.Message;
    //TODO - log to file
}

শেষ পর্যন্ত কোডটি ব্যবহার করুন:

Datamodel.SubmitChangesWithDetailException();

9

কেবল অতিরিক্ত তথ্যের সাথে অবদান রাখতে চাই: আমার একই সমস্যা ছিল এবং এটি কারণ ইনকামিং ডেটাগুলির জন্য ক্ষেত্রটি যথেষ্ট পরিমাণে বড় ছিল না এবং এই থ্রেডটি এটি সমাধান করতে আমাকে সহায়তা করেছিল (শীর্ষ উত্তরটি এটি সমস্ত পরিষ্কার করে)।

তবে এটি সম্ভাব্য কারণগুলি কী কারণ হতে পারে তা জানা খুব গুরুত্বপূর্ণ।

আমার ক্ষেত্রে আমি এই জাতীয় ক্ষেত্রটি দিয়ে টেবিলটি তৈরি করছিলাম:

Select '' as  Period, * From Transactions Into #NewTable

অতএব "পিরিয়ড" ক্ষেত্রটির একটি দৈর্ঘ্য শূন্য ছিল এবং সন্নিবেশ ক্রিয়াকলাপগুলি ব্যর্থ করে দেয়। আমি এটিকে "এক্সএক্সএক্সএক্সএক্সএক্সএক্স" এ পরিবর্তন করেছি যা আগত ডেটার দৈর্ঘ্য এবং এটি এখন সঠিকভাবে কাজ করেছে (কারণ ফিল্ডটির এখন 6 টি লেন্ট ছিল)।

আমি আশা করি এটি একই সমস্যা সহ যে কাউকে সহায়তা করবে :)


7

আরেকটি পরিস্থিতি যেখানে আপনি এই ত্রুটিটি পেতে পারেন তা হ'ল:

আমার একই ত্রুটি ছিল এবং কারণটি ছিল যে কোনও সংঘের ডেটা প্রাপ্ত একটি INSERT বিবৃতিতে, কলামগুলির ক্রমটি মূল টেবিলের চেয়ে পৃথক ছিল। যদি আপনি # টেবিল 3 এ অর্ডারটি a, b, c তে পরিবর্তন করেন তবে আপনি ত্রুটিটি ঠিক করবেন।

select a, b, c into #table1
from #table0

insert into #table1
    select a, b, c from #table2
    union
    select a, c, b from #table3

7

এসকিএল সার্ভারে আপনি এটি সেট এএনএসআই_ওয়ার্নিংস অফ ব্যবহার করতে পারেন:

        using (SqlConnection conn = new SqlConnection("Data Source=XRAYGOAT\\SQLEXPRESS;Initial Catalog='Healthy Care';Integrated Security=True"))
        {
            conn.Open();

            using (var trans = conn.BeginTransaction())
            {
                try
                {
                    using cmd = new SqlCommand("", conn, trans))
                    { 

                    cmd.CommandText = "SET ANSI_WARNINGS OFF";
                    cmd.ExecuteNonQuery();

                    cmd.CommandText = "YOUR INSERT HERE";
                    cmd.ExecuteNonQuery();

                    cmd.Parameters.Clear();

                    cmd.CommandText = "SET ANSI_WARNINGS ON";
                    cmd.ExecuteNonQuery();

                    trans.Commit();
                    }
                }
                catch (Exception)
                {

                    trans.Rollback();
                }

            }

            conn.Close();

        }

7

আমারো একই ইস্যু ছিল. দৈর্ঘ্য আমার কলামের খুব ছোট ছিল।

আপনি যা করতে পারেন তা হয় দৈর্ঘ্য বৃদ্ধি করা বা আপনি ডাটাবেসে রাখতে চান পাঠ্যটি ছোট করা।


7

ওয়েব অ্যাপ্লিকেশন পৃষ্ঠেও এই সমস্যা দেখা দিয়েছে। শেষ পর্যন্ত সন্ধান করা গেল যে একই ত্রুটি বার্তাটি নির্দিষ্ট টেবিলের এসকিউএল আপডেট বিবৃতি থেকে আসে।

পরিশেষে পরে আবিষ্কার করলেন যে সম্পর্কিত ইতিহাস সারণিতে (ক) এর কলাম সংজ্ঞাটি nvarcharনির্দিষ্ট কিছু ক্ষেত্রে মূল সারণী কলামের ধরণের দৈর্ঘ্যের মানচিত্র তৈরি করে না ।


4

টেবিলে সমস্যাযুক্ত কলামগুলির আকার বাড়ানোর পরেও আমার একই সমস্যা ছিল।

tl; dr: সংশ্লিষ্ট সারণী প্রকারের সাথে মেলানো কলামগুলির দৈর্ঘ্য বাড়ানোর প্রয়োজনও হতে পারে।

আমার ক্ষেত্রে, ত্রুটিটি মাইক্রোসফ্ট ডায়নামিক্স সিআরএম-এর ডেটা এক্সপোর্ট পরিষেবা থেকে এসেছিল, যা সিআরএম ডেটা কোনও এসকিউএল সার্ভার ডিবি বা অ্যাজুরি এসকিউএল ডিবিতে সিঙ্ক করার অনুমতি দেয়।

দীর্ঘ তদন্তের পরে, আমি সিদ্ধান্তে পৌঁছেছি যে ডেটা এক্সপোর্ট পরিষেবা অবশ্যই টেবিল-মূল্যবান প্যারামিটার ব্যবহার করবে :

আপনি কোনও অস্থায়ী টেবিল বা অনেকগুলি পরামিতি তৈরি না করে কোনও লেনদেন-এসকিউএল বিবৃতিতে বা একটি রুটিনে একাধিক সারি ডেটা প্রেরণে টেবিল-মূল্যবান প্যারামিটার ব্যবহার করতে পারেন।

আপনি উপরের ডকুমেন্টেশনে দেখতে পাচ্ছেন, ডাটা ইনজেশন পদ্ধতি তৈরি করতে টেবিল প্রকারগুলি ব্যবহৃত হয়:

CREATE TYPE LocationTableType AS TABLE (...);
CREATE PROCEDURE dbo.usp_InsertProductionLocation
  @TVP LocationTableType READONLY

দুর্ভাগ্যক্রমে, কোনও সারণির ধরণের পরিবর্তন করার কোনও উপায় নেই, সুতরাং এটি ফেলে দেওয়া এবং পুনরায় তৈরি করতে হবে। যেহেতু আমার টেবিলটির 300 টিরও বেশি ক্ষেত্র (😱) রয়েছে, তাই আমি টেবিলের কলাম সংজ্ঞা (কেবলমাত্র [table_name]আপনার টেবিলের নামটি দিয়ে প্রতিস্থাপন করুন ) এর উপর ভিত্তি করে সংশ্লিষ্ট সারণী প্রকার তৈরির সুবিধার্থে একটি অনুসন্ধান তৈরি করেছি :

SELECT 'CREATE TYPE [table_name]Type AS TABLE (' + STRING_AGG(CAST(field AS VARCHAR(max)), ',' + CHAR(10)) + ');' AS create_type
FROM (
  SELECT TOP 5000 COLUMN_NAME + ' ' + DATA_TYPE
      + IIF(CHARACTER_MAXIMUM_LENGTH IS NULL, '', CONCAT('(', IIF(CHARACTER_MAXIMUM_LENGTH = -1, 'max', CONCAT(CHARACTER_MAXIMUM_LENGTH,'')), ')'))
      + IIF(DATA_TYPE = 'decimal', CONCAT('(', NUMERIC_PRECISION, ',', NUMERIC_SCALE, ')'), '')
      AS field
  FROM INFORMATION_SCHEMA.COLUMNS
  WHERE TABLE_NAME = '[table_name]'
  ORDER BY ORDINAL_POSITION) AS T;

সারণী প্রকারটি আপডেট করার পরে, ডেটা রফতানি পরিষেবাটি আবারও সঠিকভাবে কাজ শুরু করে! :)


2

যখন আমি আমার সঞ্চিত পদ্ধতিটি কার্যকর করার চেষ্টা করছিলাম তখন আমারও একই সমস্যা হয়েছিল কারণ কলামটির আকার যেটি আমাকে কিছু ডেটা যুক্ত করতে হবে সেটি আমি যে ডেটা যুক্ত করতে চাই তার চেয়ে কম।

আপনি কলামের তথ্য প্রকারের আকার বাড়াতে বা আপনার ডেটার দৈর্ঘ্য হ্রাস করতে পারেন।


1

আর একটি পরিস্থিতি, যেখানে এই ত্রুটিটি দেখা দিতে পারে তা এসকিউএল সার্ভার ম্যানেজমেন্ট স্টুডিওতে। আপনার টেবিলে যদি আপনার "পাঠ্য" বা "এনটেক্সট" ক্ষেত্র থাকে তবে আপনি কোন ধরণের ক্ষেত্র আপডেট করছেন তা বিবেচনাধীন নয় (উদাহরণস্বরূপ বিট বা পূর্ণসংখ্যা)। দেখে মনে হচ্ছে যে স্টুডিওগুলি পুরো "ntext" ক্ষেত্রগুলি লোড করে না এবং পরিবর্তিতগুলির পরিবর্তে সমস্ত ক্ষেত্র আপডেট করে। সমস্যা সমাধানের জন্য, ম্যানেজমেন্ট স্টুডিওতে "পাঠ্য" বা "ntext" ক্ষেত্রগুলি বাদ দিন


1
কমা, পিরিয়ড যোগ করে এবং আপনার ব্যাকরণ ত্রুটিগুলি ঠিক করে দয়া করে আপনার উত্তরটি পুনরায় প্রকাশের বিষয়টি বিবেচনা করুন।
জর্জ পামফিলিস 12:58

এই উত্তরটি আমাকে সহায়তা করেছিল - আমার এনভারচর ক্ষেত্রগুলি যথেষ্ট বড় তবে আমার একটি নেটেক্সট ক্ষেত্র রয়েছে। ম্যানেজমেন্ট স্টুডিও / এসএমএসএস-এ কিছু ত্রুটি বলে মনে হচ্ছে।

0

গৃহীত উত্তরের অধীনে কেভিন পোপের মন্তব্যটি আমার প্রয়োজনীয় ছিল।

সমস্যা নেই, আমার ক্ষেত্রে, আমি আমার টেবিলের উপর সংজ্ঞায়িত ট্রিগার যে নিরীক্ষা টেবিলের মধ্যে আপডেটের সন্নিবেশ হবে / লেনদেনের সন্নিবেশ ছিল ছিল, কিন্তু নিরীক্ষা টেবিল একটি ডাটা টাইপ মেলেনি যেখানে সঙ্গে একটি কলাম ছিল VARCHAR(MAX)মূল সারণিতে হিসাবে সংরক্ষিত হয় VARCHAR(1)মধ্যে অডিট টেবিল, সুতরাং আমার ট্রিগারগুলি ব্যর্থ হয়েছিল যখন আমি VARCHAR(1)মূল টেবিল কলামের চেয়ে বড় কিছু সন্নিবেশ করতাম এবং আমি এই ত্রুটি বার্তাটি পাই।


0

আমি একটি আলাদা কৌশল, ক্ষেত্রগুলি ব্যবহার করেছি যা কিছু জায়গায় 8 কে বরাদ্দ করা হয়। এখানে প্রায় 50/100 ব্যবহার করা হয়।

declare @NVPN_list as table 
nvpn            varchar(50)
,nvpn_revision  varchar(5)
,nvpn_iteration INT
,mpn_lifecycle  varchar(30)
,mfr            varchar(100)
,mpn            varchar(50)
,mpn_revision   varchar(5)
,mpn_iteration  INT
-- ...
) INSERT INTO @NVPN_LIST 
SELECT  left(nvpn           ,50)    as nvpn
        ,left(nvpn_revision ,10)    as nvpn_revision
        ,nvpn_iteration
        ,left(mpn_lifecycle ,30)
        ,left(mfr           ,100)
        ,left(mpn           ,50)
        ,left(mpn_revision  ,5)
        ,mpn_iteration
        ,left(mfr_order_num ,50)
FROM [DASHBOARD].[dbo].[mpnAttributes] (NOLOCK) mpna

আমি গতি চেয়েছিলাম, যেহেতু আমার কাছে মোট 1 এম রেকর্ড রয়েছে এবং সেগুলির মধ্যে 28 কে লোড করুন।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.