tutorial - w3schools sql




সন্নিবেশ করার চেষ্টা করার সময় ত্রুটি, স্ট্রিং বা বাইনারি তথ্য কঙ্কাল করা হবে (8)

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

প্রথম সাহায্যকারী বর্গ তৈরি করুন:

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);
                    }

                }
            }
        }
    }
}

তারপর SubmitChanges জন্য মোড়ানো প্রস্তুতকারক:

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();

আমি নিম্নলিখিত লাইন দিয়ে data.bat ফাইল চালাচ্ছি:

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

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?


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

আমারও একই ত্রুটি ছিল এবং কারণ একটি ইউনিসেটারের বিবৃতিতে যে একটি ইউনিয়ন থেকে তথ্য পেয়েছিল, কলামের আদেশ মূল টেবিল থেকে আলাদা ছিল। যদি আপনি # টেবিল 3 এ একটি, বি, সি এ ক্রমটি পরিবর্তন করেন তবে আপনি ত্রুটিটি ঠিক করবেন।

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

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

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


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

অবশেষে তখন ধারণা করা হয়েছিল যে ইতিহাসের টেবিলে সম্পর্কিত কলাম nvarchar কিছু নির্দিষ্ট ক্ষেত্রে nvarchar মূল টেবিল কলামের nvarchar মানচিত্র করে নি।

আশা করি এই ইঙ্গিতটি অন্য কাউকেও সাহায্য করবে ..;)


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

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

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

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

অস্থায়ী টেবিল বা অনেক প্যারামিটার তৈরি না করে আপনি ট্র্যাজ্যাক্ট-এসকিউএল স্টেটমেন্টে ট্র্যাক্ট্যাক্ট-এসকিউএল স্টেটমেন্ট বা রুটিন, যেমন স্টোরেজ পদ্ধতি বা ফাংশনটিতে একাধিক সারি পাঠাতে টেবিল-মূল্যমান পরামিতি ব্যবহার করতে পারেন।

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

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

দুর্ভাগ্যবশত, একটি টেবিল প্রকার পরিবর্তন করার কোন উপায় নেই, তাই এটি সম্পূর্ণভাবে বাদ দিতে হবে এবং পুরোপুরি পুনরূদ্ধার করা হবে। যেহেতু আমার টেবিলের 300 টিরও বেশি ক্ষেত্র (😱) আছে, তাই আমি টেবিলের কলামের [table_name] ভিত্তিতে সংশ্লিষ্ট টেবিল প্রকার তৈরির জন্য একটি প্রশ্ন তৈরি করেছি (কেবল আপনার টেবিলের নামের সাথে [table_name] প্রতিস্থাপন করুন [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;

টেবিল প্রকার হালনাগাদ করার পর, ডেটা এক্সপোর্ট সার্ভিস আবারও সঠিকভাবে কাজ শুরু করে! :)


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


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

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

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

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

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

আমি এই একই সমস্যা সঙ্গে কেউ সাহায্য আশা করি :)


@ গমাস্ট্রোস এর উত্তর থেকে

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

string or binary data would be truncated 

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

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





sql-server