<টিএল; ডিআর> সমস্যাটি বরং সাধারণ, আসলে: আপনি ইনপুট প্যারামিটারের ডেটাটাইপের সাথে ঘোষিত এনকোডিংটি (এক্সএমএল ঘোষণায়) মেলাচ্ছেন না। আপনি যদি ম্যানুয়ালি <?xml version="1.0" encoding="utf-8"?><test/>
স্ট্রিংয়ে যুক্ত হন, তবে SqlParameter
এটিকে টাইপযুক্ত হিসাবে ঘোষণা করে SqlDbType.Xml
বা SqlDbType.NVarChar
আপনাকে "এনকোডিং স্যুইচ করতে অক্ষম" ত্রুটি দেয় give তারপরে, টি-এসকিউএল এর মাধ্যমে ম্যানুয়ালি সন্নিবেশ করার সময় utf-16
, আপনি ঘোষিত এনকোডিংটি যেহেতু স্যুইচ করেছেন , আপনি স্পষ্টভাবে একটি VARCHAR
স্ট্রিং সন্নিবেশ করছিলেন (উচ্চ-কেস "এন" এর সাথে উপস্থাপিত হয়নি, সুতরাং একটি 8-বিট এনকোডিং যেমন ইউটিএফ -8) এবং একটি NVARCHAR
স্ট্রিং নয় (একটি উচ্চ-কেস "N" এর সাথে উপসর্গযুক্ত, সুতরাং 16 বিট ইউটিএফ -16 এলই এনকোডিং)।
ফিক্সটি এতটা সহজ হওয়া উচিত:
- প্রথম ক্ষেত্রে, ঘোষণাটি যুক্ত করার সময় উল্লেখ করুন
encoding="utf-8"
: কেবল এক্সএমএল ঘোষণাটি যুক্ত করবেন না।
- দ্বিতীয় ক্ষেত্রে, ঘোষণাপত্রটি যুক্ত করার সময় উল্লেখ করুন
encoding="utf-16"
: হয়
- কেবল এক্সএমএল ঘোষণাটি যুক্ত করবেন না, বা
- ইনপুট প্যারামিটার প্রকারে কেবল একটি "এন" যুক্ত করুন: :-) এর
SqlDbType.NVarChar
পরিবর্তে SqlDbType.VarChar
(অথবা সম্ভবত ব্যবহারে স্যুইচ করুন SqlDbType.Xml
)
(বিস্তারিত প্রতিক্রিয়া নীচে রয়েছে)
এখানে সমস্ত উত্তর অত্যধিক জটিল এবং অপ্রয়োজনীয় (যথাক্রমে খ্রিস্টান এবং জনের উত্তরের জন্য 121 এবং 184-এর আপ-ভোট নির্বিশেষে)। তারা হয়ত ওয়ার্কিং কোড সরবরাহ করতে পারে তবে তাদের কেউই আসলে প্রশ্নের উত্তর দেয় না। সমস্যাটি হ'ল এই প্রশ্নটি কেউ সত্যই বুঝতে পারে নি, যা শেষ পর্যন্ত এসকিউএল সার্ভারে এক্সএমএল ডেটাটাইপ কীভাবে কাজ করে তা সম্পর্কে। এই দু'টি স্পষ্ট বুদ্ধিমান ব্যক্তির বিরুদ্ধে কিছুই নয়, তবে এক্সএমএলকে সিরিয়ালায়িত করার সাথে এই প্রশ্নের কিছুটা করার নেই। এসকিউএল সার্ভারে এক্সএমএল ডেটা সংরক্ষণ করা এখানে যা বোঝানো হচ্ছে তার চেয়ে অনেক সহজ।
আপনি এসকিউএল সার্ভারে কীভাবে এক্সএমএল ডেটা তৈরি করবেন তার নিয়মগুলি মেনে চলেন যতক্ষণ না এক্সএমএল উত্পাদিত হয় তা বিবেচ্য নয়। এই প্রশ্নের উত্তরে আমার আরও বিশদ ব্যাখ্যা রয়েছে (নীচে বর্ণিত পয়েন্টগুলি বর্ণনা করার জন্য ওয়ার্কিং উদাহরণ কোড সহ) এসকিউএল সার্ভারে এক্সএমএল সন্নিবেশ করার সময় কীভাবে "এনকোডিং স্যুইচ করতে অক্ষম" ত্রুটিটি সমাধান করা যায় তবে মূল বিষয়গুলি হ'ল:
- এক্সএমএল ঘোষণাটি isচ্ছিক
- এক্সএমএল ডেটাটাইপ সর্বদা ইউসিএস -2 / ইউটিএফ -16 এলই হিসাবে স্ট্রিং সঞ্চয় করে
- যদি আপনার এক্সএমএলটি ইউসিএস -২ / ইউটিএফ -16 এলই হয়, তবে আপনি:
- ডেটাটি হয়
NVARCHAR(MAX)
বা XML
/ SqlDbType.NVarChar
(ম্যাক্সেসাইজ = -1) হিসাবে পাস করুন SqlDbType.Xml
, বা যদি স্ট্রিং আক্ষরিক ব্যবহার করে থাকেন তবে অবশ্যই এটি একটি উচ্চ-কেস "এন" এর সাথে উপসর্গ করা উচিত।
- যদি এক্সএমএল ঘোষণাটি নির্দিষ্ট করে থাকে তবে এটি অবশ্যই "ইউসিএস -২" বা "ইউটিএফ -16" হতে হবে (এখানে কোনও আসল পার্থক্য নেই)
- যদি আপনার এক্সএমএল 8-বিট এনকোডড থাকে (উদাঃ "ইউটিএফ -8" / "আইসো -8859-1" / "উইন্ডোজ-1252") তবে আপনি:
- এক্সএমএল ঘোষণাটি নির্দিষ্ট করতে হবে যদি এনকোডিংটি ডাটাবেজের ডিফল্ট কোলেশন দ্বারা নির্দিষ্ট কোড পৃষ্ঠার চেয়ে আলাদা হয়
- আপনাকে অবশ্যই ডেটাতে
VARCHAR(MAX)
/ SqlDbType.VarChar
(ম্যাক্সেসাইজ = -1) হিসাবে পাস করতে হবে , বা যদি স্ট্রিং আক্ষরিক ব্যবহার করে থাকে তবে অবশ্যই এটি একটি উচ্চ-কেস "এন" এর সাথে উপস্থাপিত হবে না ।
- 8-বিট এনকোডিং যাই ব্যবহার করা হোক না কেন, এক্সএমএল ঘোষণায় উল্লিখিত "এনকোডিং" অবশ্যই বাইটের প্রকৃত এনকোডিংয়ের সাথে মিলে যাবে।
- 8 বিট এনকোডিংটি এক্সএমএল ডেটাটাইপ দ্বারা UTF-16 এলিতে রূপান্তরিত হবে
উপরে উল্লিখিত পয়েন্টগুলি মাথায় রেখে এবং স্ট্রিংগুলি দেওয়া হয়েছে। নেট সর্বদা ইউটিএফ -16 এলই / ইউসিএস -2 এলই হয় (এনকোডিংয়ের ক্ষেত্রে এটির মধ্যে কোনও পার্থক্য নেই), আমরা আপনার প্রশ্নের উত্তর দিতে পারি:
আমার যখন স্ট্রিং রাইটারটি স্ট্রিংয়ের পরে যখন স্ট্রিংয়ের প্রয়োজন হয় তখন কোনও অবজেক্টের সিরিয়ালাইজ করার জন্য আমার ব্যবহার না করা কেন এমন কোনও কারণ আছে?
না, আপনার StringWriter
কোডটি ঠিক আছে বলে মনে হচ্ছে (কমপক্ষে আমি প্রশ্ন থেকে ২ য় কোড ব্লক ব্যবহার করে আমার সীমাবদ্ধ পরীক্ষায় কোনও সমস্যা দেখছি না)।
ইউটিএফ -16 এ (এনএমএল ট্যাগে) তখন এনকোডিংটি সেট করবেন না?
এক্সএমএল ঘোষণা সরবরাহ করার প্রয়োজন নেই। এটি অনুপস্থিত থাকলে, এনকোডিংটি ইউটিএফ -১ LE লে হিসাবে ধরে নেওয়া হয় যদি আপনি এসকিউএল সার্ভারে NVARCHAR
(যেমন SqlDbType.NVarChar
) বা XML
(ie SqlDbType.Xml
) হিসাবে স্ট্রিংটি পাস করেন । VARCHAR
(যেমন SqlDbType.VarChar
) হিসাবে পাস করার সাথে সাথে এনকোডিংটি ডিফল্ট 8-বিট কোড পৃষ্ঠা হিসাবে ধরে নেওয়া হয় । আপনার যদি কোনও মানহীন-এএসসিআইআই অক্ষর থাকে (উদাহরণস্বরূপ 128 এবং এর চেয়ে বেশি মান) এবং এরূপ হিসাবে চলে যাচ্ছেনVARCHAR
তবে আপনি সম্ভবত দেখতে পাবেন "?" বিএমপি অক্ষরের জন্য এবং "??" এসকিউএল সার্ভার হিসাবে পরিপূরক অক্ষরের জন্য ইউটিএফ -১ / / ইউসিএস -২ এ আবার রূপান্তর করার আগে ইউটিএফ -১ string স্ট্রিংটিকে বর্তমান নেটবেস-এর কোড পৃষ্ঠার .NET থেকে একটি 8-বিট স্ট্রিংয়ে রূপান্তর করবে। তবে আপনার কোনও ত্রুটি হওয়া উচিত নয়।
অন্যদিকে, আপনি যদি এক্সএমএল ঘোষণাটি নির্দিষ্ট করে থাকেন তবে অবশ্যই আপনাকে 8-বিট বা 16-বিট ডেটাটাইপটি ম্যাচিং করে এসকিউএল সার্ভারে প্রবেশ করতে হবে । সুতরাং যদি আপনার কাছে কোনও ঘোষণা রয়েছে যে এনকোডিংটি হয় ইউসিএস -২ বা ইউটিএফ -16, তবে আপনাকে অবশ্যই হিসাবে SqlDbType.NVarChar
বা হিসাবে পাস করতে হবেSqlDbType.Xml
। অথবা, যদি আপনার কাছে কোনও ঘোষণা থাকে যা উল্লেখ করে যে এনকোডিংটি 8-বিট বিকল্পগুলির মধ্যে একটি (যেমনUTF-8
, Windows-1252
, iso-8859-1
, ইত্যাদি), তারপর আপনি আবশ্যক হিসাবে পাস SqlDbType.VarChar
। যথাযথ 8 বা 16-বিট এসকিউএল সার্ভার ডেটাটাইপের সাথে ঘোষিত এনকোডিংটি মেলে ফেলতে ব্যর্থ হওয়ার ফলে আপনি যে "এনকোডিংটি স্যুইচ করতে অক্ষম" ত্রুটি হয়ে উঠবে।
উদাহরণস্বরূপ, আপনার StringWriter
ভিত্তিক সিরিয়ালাইজ কোডটি ব্যবহার করে , আমি কেবল এক্সএমএলের ফলাফলযুক্ত স্ট্রিংটি প্রিন্ট করেছি এবং এটি এসএসএমএসে ব্যবহার করেছি। আপনি নীচে দেখতে পারেন, এক্সএমএল ঘোষণা অন্তর্ভুক্ত করা হয়েছে (কারণStringWriter
একটি বিকল্প নেই OmitXmlDeclaration
মত XmlWriter
, যা যতদিন আপনি সঠিক SQL সার্ভার ডাটাটাইপ হিসাবে স্ট্রিং পাস কোন সমস্যা ভঙ্গি করে):
DECLARE @Xml XML = N'<?xml version="1.0" encoding="utf-16"?>
<string>Test ሴ😸</string>';
SELECT @Xml;
আপনি দেখতে পাচ্ছেন, এটি মানক ASCII এর বাইরেও অক্ষরগুলি পরিচালনা করে ሴ
হল বিএমপি কোড পয়েন্ট ইউ + 1234 এবং 😸
এটি পরিপূরক চরিত্রের কোড পয়েন্ট ইউ + 1F638। তবে, নিম্নলিখিত:
DECLARE @Xml XML = '<?xml version="1.0" encoding="utf-16"?>
<string>Test ሴ😸</string>';
নিম্নলিখিত ত্রুটির ফলাফল:
Msg 9402, Level 16, State 1, Line XXXXX
XML parsing: line 1, character 39, unable to switch the encoding
তবে, সমস্ত ব্যাখ্যা একদিকে রেখে আপনার মূল প্রশ্নের সম্পূর্ণ সমাধান:
আপনি স্পষ্টভাবে হিসাবে স্ট্রিং পাস SqlDbType.VarChar
। সুইচSqlDbType.NVarChar
এবং এটি এক্সএমএল ঘোষণাটি সরানোর অতিরিক্ত পদক্ষেপের প্রয়োজন ছাড়াই কাজ করবে। এটি SqlDbType.VarChar
এক্সএমএল ঘোষণা রাখার এবং অপসারণের চেয়ে বেশি পছন্দ করা হয় কারণ এক্সএমএল অ-মানক-এএসসিআইআই অক্ষর অন্তর্ভুক্ত করা হলে এই সমাধানটি ডেটা ক্ষতি রোধ করবে। উদাহরণ স্বরূপ:
DECLARE @Xml2 XML = '<string>Test ሴ😸</string>';
SELECT @Xml2;
আপনি দেখতে পাচ্ছেন, এবার কোনও ত্রুটি নেই তবে এখন ডেটা-লোকসান 🙀