এসকিউএল সার্ভার 2014 এ সিএলআর ক্র্যাশ করছে (উইন্ডোজ 2012 আর 2)


12

আমার কাছে এই ছোট সিএলআর রয়েছে যা কলামগুলিতে একটি রেগেক্স ফাংশন করে।

উইন্ডোজ সার্ভার 2012R2 এ এসকিউএল সার্ভার 2014 (12.0.2000) চলাকালীন প্রক্রিয়াটি ক্র্যাশ হয়ে যায়

এমএসজি 0, স্তর 11, রাজ্য 0, লাইন 0 বর্তমান কমান্ডে একটি গুরুতর ত্রুটি ঘটেছে। ফলাফল, যদি থাকে, বাতিল করা উচিত।

এবং যদি আমি করি তবে স্ট্যাক ডাম্প দেয়

select count (*) from table where (CLRREGEX,'Regex')

কিন্তু যখন আমি করি

select * from table where (CLRREGEX,'Regex') 

এটি সারি প্রদান করে।

উইন্ডোজ 8.1 এ চলমান একই এসকিউএল সার্ভার বিল্ডে নিখুঁতভাবে কাজ করে।

কোন ধারনা?

- সম্পাদনা এটি যতটা সহজ

using System;
using System.Collections.Generic;
using System.Text;
using System.Data.SqlTypes;           //SqlString, SqlInt32, SqlBoolean
using System.Text.RegularExpressions; //Match, Regex
using Microsoft.SqlServer.Server;     //SqlFunctionAttribute
public partial class UserDefinedFunctions
{
    public static readonly RegexOptions Options = RegexOptions.IgnorePatternWhitespace | RegexOptions.Multiline;
    [SqlFunction]
    [Microsoft.SqlServer.Server.SqlFunction(IsDeterministic = true, IsPrecise = true)]
    public static SqlBoolean RegExMatch(SqlString input, SqlString pattern)
    {
        if (input.IsNull || pattern.IsNull) //nulls dont qualify for a match
            return SqlBoolean.False;
    return Regex.IsMatch(input.Value, pattern.Value, RegexOptions.IgnoreCase);
    }
}

সুতরাং সামান্য পরিবর্তন দ্বারা এখন এটি কাজ করে: সি # এর প্রধান পাঠ টিএসকিউএল এর মতোই বলে মনে হচ্ছে অন্তর্নিহিত ডেটা রূপান্তর সম্পর্কে সতর্ক থাকুন।

using System;
using System.Text;
using System.Data.SqlTypes;           //SqlString, SqlInt32, SqlBoolean
using System.Text.RegularExpressions; //Match, Regex
using Microsoft.SqlServer.Server;     //SqlFunctionAttribute
public partial class UserDefinedFunctions
{
public static readonly RegexOptions Options = RegexOptions.IgnorePatternWhitespace | RegexOptions.Singleline | RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.CultureInvariant;

    [Microsoft.SqlServer.Server.SqlFunction(IsDeterministic = true, IsPrecise = true, DataAccess = DataAccessKind.Read)]
    public static SqlBoolean RegExMatch(SqlString input, SqlString pattern)
{
    if (input.IsNull || pattern.IsNull) //nulls dont qualify for a match
        return SqlBoolean.False;
    string sqldata = input.ToString();
    string regex = pattern.ToString();
    return Regex.IsMatch(sqldata, regex);
 }

এটি কি সমস্ত নিদর্শনগুলির জন্য ঘটে বা কেবল এটির জন্য? এটি একটি অদক্ষ প্যাটার্ন (যেমন অতিরিক্ত ব্যাকট্র্যাকিং বা অপ্রয়োজনীয় ক্যাপচার) হতে পারে। আপনার ম্যাচটাইমআউট সম্পত্তি নির্ধারণ করা উচিত (। নেট ফ্রেমওয়ার্ক 4.5 এ নতুন)। আপনি নিজেই রেজিএক্স ফাংশনটি কোড করেছিলেন? যদি তাই হয়, আপনি স্থির বা উদাহরণ RegEx পদ্ধতি ব্যবহার করছেন? হয় SqlFunctionপদ্ধতি হিসাবে চিহ্নিত IsDeterministic=true? সমাবেশ হিসাবে চিহ্নিত করা হয় SAFE?
সলোমন রুটজকি

2
এই টেবিলগুলি কত বড়? এছাড়াও, আপনি সমস্যার বিবৃতিগুলির জন্য আনুমানিক পরিকল্পনার একটি সমান্তরাল অপারেটর আছে কিনা তা পরীক্ষা করতে পারেন? যদি হ্যাঁ, আপনি কী পরীক্ষা করতে পারতেন যে সমস্যাটি সমান্তরালতা ছাড়াই অর্থাত্ একটি MAXDOP = 1 ইঙ্গিত সহ ঘটে।
অমিত ব্যানার্জি

2
ডুপ্লিকেট [SqlFunction]বৈশিষ্ট্য বাদে কোডটি দুর্দান্ত দেখাচ্ছে । এটা কি সঠিক কোড? আমি মনে করি না যে এটি সংকলন হবে। ফ্রেমওয়ার্ক সংস্করণ ২.০ / 3.0.০ / non. issue পার্থক্যটি একটি নন-ইস্যু, কারণ আপনি এসকিউএল সার্ভার ২০১৪ যা সিএলআর সংস্করণ ৪ এ আবদ্ধ, আপনি যেহেতু সেই সার্ভারে যা কিছু ব্যবহার করছেন the সার্ভারের সমস্যা 32-বিট দেখাচ্ছে? অন্যান্য সার্ভারের সাথে তুলনা করে এটি কত স্মৃতি? এবং আপনি কি ত্রুটি পেয়ে ঠিক এসকিউএল সার্ভার লগগুলি পরীক্ষা করেছেন?
সলোমন রুটজকি

2
.NET এর সঠিক সংস্করণটি সমস্যার সাথে সম্পর্কিত নয়, যদিও এটি জানা ভাল লাগবে যে সমস্ত সার্ভারের সর্বনিম্ন 4.5 আছে কি না কারণ এর অর্থ আপনি নতুন MatchTimeoutসম্পত্তিটি ব্যবহার করতে পারবেন । তবে আমি মনে করি না যে এটি যদি সত্যিই সমস্যা হয় তবে আপনি যদি কেবল সর্বোচ্চ পাঁচটি পাস করে থাকেন। এটি সম্ভবত সম্ভব যে এই একটি মেশিনে। নেট ফ্রেমওয়ার্কের একটি দূষিত ইনস্টল রয়েছে এবং ট্রাউট ফিশিং ক্রিয়াকলাপ বন্ধ হয়ে যাওয়ার পরে এটি মেরামত করা যেতে পারে ;-)। এছাড়াও, [0-9].*সহজ তবে অকার্যকর কারণ এটি প্রথম অঙ্কের পরে সমস্ত অক্ষরের সাথে মেলে, যদি কোনও হয়; শুধু [0-9]একটি জন্য ব্যবহার IsMatchকরা ভাল।
সলোমন রুটজকি

1
আপনি কেন বদলে DataAccessKindগেলেন Read? এটি কেবল এটি ধীর করে দেয় এবং আপনি কোনও ডেটা অ্যাক্সেস করেন না। এছাড়াও, আমি বুঝতে পারি যে এটি এখন কাজ করছে বলে মনে হচ্ছে, তবে আমি সম্পত্তিটির ToString()বিপরীতে পদ্ধতিটি ব্যবহারে সতর্ক Valueথাকব কারণ আমি মনে করি না যে টস্ট্রিং এনকোডিংগুলি সঠিকভাবে পরিচালনা করে না বা এর মতো কিছু like আপনার ডাটাবেস কোলেশন সেট করা কি? অবশ্যই, আমি কেবল আপনার উপরে একটি মন্তব্য পুনরায় পড়েছি এবং দেখুন যে কলামটি এনভিচারারের পরিবর্তে VARCHAR। সেই ক্ষেত্রটির কি ডাটাবেসের চেয়ে আলাদা কোলেশন আছে?
সলোমন রুটজকি

উত্তর:


4

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

SELECT os_language_version,
       DATABASEPROPERTYEX(N'{name of DB where Assembly exists}', 'LCID') AS 'DatabaseLCID'
FROM   sys.dm_os_windows_info;

যদি সেগুলি আলাদা হয় তবে আপনি অবশ্যই কিছু "বিজোড়" আচরণ পেতে পারেন, যেমন আপনি যা দেখছেন। বিষয়টি হ'ল:

  • SqlStringএটি কেবল পাঠ্যের চেয়েও বেশি অন্তর্ভুক্ত: এতে ডেটাবেসটির ডিফল্ট সমষ্টি রয়েছে যেখানে সমাবেশ বিদ্যমান। কোলেশনটি দুটি টুকরো তথ্যের সমন্বয়ে গঠিত: লোকেল তথ্য (যেমন এলসিআইডি), এবং তুলনা বিকল্পগুলি (অর্থাত্ স্ক্যালকম্পেরঅ্যাপশনস) যা কেস, অ্যাকসেন্টস, কানা, প্রস্থ বা সমস্ত কিছুর সংবেদনশীলতা (বাইনারি এবং বাইনারি 2) সম্পর্কিত বিশদ বিবরণ করে।
  • .NET- এ স্ট্রিং অপারেশনগুলি স্পষ্টভাবে লোকেল না দেওয়া পর্যন্ত বর্তমান থ্রেডের লোকেল তথ্য ব্যবহার করুন যা উইন্ডোজ (যেমন অপারেটিং সিস্টেম / ওএস) এ সেট করা আছে।

দ্বন্দ্ব সাধারণত যখন ব্যবহার না করেই একটি SqlString পরামিতি উল্লেখ ঘটে .Valueবা .ToString()যেমন যে এটি একটি অন্তর্নিহিত রূপান্তর করে SqlString। সেক্ষেত্রে এটি এলসিআইডি মেলে না বলে এক ব্যতিক্রম ঘটায়।

আপাতদৃষ্টিতে অন্যান্য পরিস্থিতি রয়েছে যেমন পারফর্মিং (কিছু / সমস্ত?) স্ট্রিং তুলনা, যেমন রেগেক্স ব্যবহার করার সময় এই কেসটি দেখায় (যদিও এখনও আমি এটি পুনরুত্পাদন করতে সক্ষম হইনি)।

সংশোধনের জন্য কিছু ধারণা:

আদর্শ (তুলনাগুলি কীভাবে কাজ করে সে সম্পর্কে প্রত্যাশা সর্বদা পূরণ করা হবে):

  • উইন্ডোজ বা এসকিউএল সার্ভার এলসিআইডি (ডিফল্ট ভাষা) পরিবর্তন করুন যাতে উভয়ই মেলে

আদর্শের চেয়ে কম (উইন্ডোজ লোকালের আচরণ সমতা এবং বাছাইয়ের জন্য একই নিয়ম নাও হতে পারে এবং তাই অপ্রত্যাশিত ফলাফলও হতে পারে):

  • .ToStringপদ্ধতি বা .Valueসম্পত্তি ব্যবহার করুন , যা উভয়ই এসকিউএল সার্ভার এলসিআইডি ছাড়াই স্ট্রিং ফিরিয়ে দেয় যাতে ক্রিয়াকলাপগুলি সমস্ত ওএস এলসিআইডি ব্যবহার করবে।

সাহায্য করতে পারে:

  • এটি এসকিউএল সার্ভার থেকে এলসিআইডি এবং কোলেশন সম্পর্কিত তথ্য না আনায় SqlCharsপরিবর্তে ব্যবহার করুনSqlString
  • নির্দিষ্ট করুন যে সংস্কৃতি এর দ্বারা গুরুত্বপূর্ণ নয় StringComparison.InvariantCulture:
    • String.Compare(string, string, StringComparison.InvariantCulture) অথবা String.Compare(string, string, StringComparison.InvariantCultureIgnoreCase)
    • রেজেক্সের জন্য, নির্দিষ্ট করুন RegexOptions.CultureInvariant

1

আপডেট করা হয়েছে ..

এসকিউএল ইঞ্জিন এবং উইন্ডো সার্ভারের মধ্যে @ শ্রুতজকি পয়েন্ট হিসাবে স্থানীয়করণটি আলাদা:

os_language_version স্কেল সার্ভার এলসিআইডি
1033 1039

কোডটিতে নিম্নলিখিত পরিবর্তন - বিকল্পটি সেট করা RegexOptions.CultureInvariantত্রুটিটি পেয়ে যায়। অপরিবর্তিত কোডটি একই ভাষা সেটিংসের সাথে উইন্ডোজ সার্ভার 2012R2 তে এসকিউএল সার্ভার 2012 ক্রাশ করবে না তবে এটি এসকিউএল সার্ভার ২০১৪-তে করে।

using System;
using System.Text;
using System.Data.SqlTypes;           //SqlString, SqlInt32, SqlBoolean
using System.Text.RegularExpressions; //Match, Regex
using Microsoft.SqlServer.Server;     //SqlFunctionAttribute
public partial class UserDefinedFunctions
{
public static readonly RegexOptions Options = RegexOptions.IgnorePatternWhitespace | RegexOptions.Singleline | RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.CultureInvariant;

    [Microsoft.SqlServer.Server.SqlFunction(IsDeterministic = true, IsPrecise = true)]
    public static SqlBoolean RegExMatch(SqlString input, SqlString pattern)
{
    if (input.IsNull || pattern.IsNull) //nulls dont qualify for a match
        return SqlBoolean.False;
    string sqldata = input.ToString();
    string regex = pattern.ToString();
    return Regex.IsMatch(sqldata, regex);
 }

আপনি কি দয়া করে সার্ভার যা বিপর্যয় ছিল নিম্নলিখিত চালানো যাবে না: SELECT os_language_version, SERVERPROPERTY('LCID') AS 'SqlServerLCID' FROM sys.dm_os_windows_info;। এটি বেশ সম্ভব যে ভাষা সেটিংসে সমস্যাটি ছিল একটি বিরোধ। আপনার সমাধানটি এখনও যাওয়ার সর্বোত্তম উপায় হতে পারে তবে সাধারণত সম্পত্তিগুলির ToString()পরিবর্তে ব্যবহারের প্রয়োজন হবে না । সুতরাং পরিস্থিতিটি নিশ্চিত করে ভাল লাগবে। ValueSqlString
সলোমন রুটজকি

আমি স্পষ্ট করার জন্য একটি উত্তর পোস্ট করেছি, তবে আপনি ভেরিয়েবলটি পাস না করে বিষয়টি সেট করে সমাধান করা উচিত নয় । জিনিস যে আপনার আসল কোড এবং নতুন কাজ কোড মধ্যে পরিবর্তিত আপনি ব্যবহার থেকে গিয়েছিলাম থেকে । আমি সন্দেহ করি আপনি যদি ব্যবহারটি পরিবর্তন করেন তবে আপনিও একই স্থির আচরণ দেখতে পাবেন । তবে আমি কেবল এটি পরীক্ষা হিসাবে করব। অন্যটির সাথে মিলে যাওয়ার জন্য উইন্ডোজ বা এসকিউএল সার্ভারের এলসিআইডি পরিবর্তন করা ভাল উপায়। আপনি বিকল্পগুলি স্থিতিশীল ভেরিয়েবলও মুছে ফেলতে পারেন। RegexOptions.CultureInvariantOptionsRegex.IsMatch(sqldata, regex)SqlString.ValueSqlString.ToString()SqlChars
সলোমন রুটজকি

হাই! আমার উত্তর গ্রহণ করার জন্য ধন্যবাদ :)। কেবলমাত্র উল্লেখ করার জন্যই, আমি আরও গবেষণা করেছি এবং আমি কী দেখছি তা যদি বুঝতে পারি তবে মূল কারণটি ওএস এবং এসকিউএল সার্ভারের মধ্যে একটি আলাদা এলসিআইডি হওয়া সম্পর্কে আমি সঠিক থাকলেও এটি .Valueসম্পত্তির সাথে সম্পর্কিত নয় বা হওয়া উচিত নয় একটি এর SqlStringযে দৃশ্যত হিসাবে একই অভ্যন্তরীণ মান .ToString()পদ্ধতি। আমি এখনও তদন্ত করছি এবং আমি যা খুশি তার সাথে আমার উত্তর আপডেট করব :)।
সলোমন রুটজকি

আমি নতুন তথ্যের আলোকে আমার উত্তরটি সামঞ্জস্য করেছি। আমি এই দৃশ্যের পুনরুত্পাদন করতে পারি না। প্রশ্নটিতে কোডটি আসলে কী আপনি ব্যবহার করছেন / ব্যবহার করছেন? তাদের মধ্যে একমাত্র আসল পার্থক্যটি হ'ল ত্রুটিগুলি RegexOptions.IgnoreCaseঅন্যটি ব্যবহার না করে। আমি একটি অনুরূপ পরিবেশ স্থাপন করেছি: উইন্ডোজ (8.0) 1033 এর এলসিআইডি ব্যবহার করে, এসকিউএল সার্ভার ডিবিতে 1039 এর এলসিআইডি রয়েছে, আপনি পোস্ট করেছেন একই রেজিএক্স ব্যবহার করে , একটি টেবিলের উপর, একটি প্যাটার্ন ব্যবহার করে, জিআইডি দ্বারা ভরা ক্ষেত্রটিতে COUNT(*)একটি করছেন ১০ মিলিয়ন সারি দিয়ে। এটি 2014 এর নয়, এটি এসকিউএল সার্ভার 2012, যদিও আমি মনে করি না যে এটির উচিত should VARCHAR'[0-3â].*'
সলোমন রুটজকি

1
সবগুলো উত্তরের জন্য ধন্যবাদ। প্রশ্নের কোডটি আমি কী ব্যবহার করছি। আমার খুব জটিল রেইগেক্স ছিল তবে খুব সাধারণ ব্যবহার করে এটি ক্র্যাশ করতে সক্ষম হয়েছিল। RegexOptions.C সংস্কৃতিবিভাজনীয় সেটিংস পরিবর্তন করা আচরণ বন্ধ করে দিয়েছে
স্পিরি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.