প্রারম্ভিক সময়ে 1 = 1 ব্যবহারের চেয়ে এসকিউএল WHERE ক্লজটি গতিশীলভাবে তৈরি করার আরও ভাল কোনও উপায় আছে কি?


110

আমি সি # তে কিছু এসকিউএল কোয়েরি তৈরি করছি । কোডে ভেরিয়েবল হিসাবে সঞ্চিত কিছু শর্তের উপর নির্ভর করে এটি পৃথক হবে।

string Query="SELECT * FROM Table1 WHERE 1=1 ";
if (condition1) 
    Query += "AND Col1=0 ";
if (condition2) 
    Query += "AND Col2=1 ";
if (condition3) 
    Query += "AND Col3=2 ";

এটি কাজ করে, তবে 1 = 1 পরীক্ষা করা মার্জিত বলে মনে হয় না। যদি আমি এটি ব্যবহার না করি, তবে প্রতিবার "যেখানে" কীওয়ার্ডটি ইতিমধ্যে কোয়েডটিতে যুক্ত হয়েছে কিনা তা আমার মনে রাখতে হবে এবং যাচাই করতে হবে।

একটি ভাল সমাধান আছে?


118
সত্যি কথা বলতে - আমি এটিও এটির মতো করব, তবে আমি 42 = 42;-) ব্যবহার করব
ফেরো

5
আমি আসলে আমার জিজ্ঞাসা সবসময় এইভাবে লিখি। কোনও শর্তটি মন্তব্য করা সহজ করে তোলে
ডেরুইজটার

4
@ ক্যাটফুড প্রথম প্রজেক্টটি আমি ইন্টার্ন হিসাবে ছিলাম তখন আমাদের সিবেস সার্ভারগুলির বিরুদ্ধে পারফরম্যান্স প্রশ্নগুলির বিশ্লেষণে সহায়তা করার জন্য সরঞ্জামগুলি রচনা করছিলাম। একটি মজাদার আবিষ্কার Select 42আমরা কয়েকশো কোয়েরিজ পেয়েছিলাম। (
উত্সাহিত

24
If I didn't use it, I would have to remember and check every time if "where" keyword was already added or not to the query- এজন্যই আপনি ব্যবহার করেন 1 = 1। ডাটাবেস ইঞ্জিনটি যেকোন উপায়ে এটি অপ্টিমাইজ করে, তাই এটি দেখতে কুৎসিত মনে হলেও সমস্যা সমাধানের এটি সহজতম উপায়।
রবার্ট হার্ভে

4
প্রদত্ত উত্তরগুলি খুব সুন্দর হলেও আমি মনে করি আপনার মূল কোডটি পড়া সবচেয়ে সহজ।
ইউওও

উত্তর:


157

শর্তগুলি একটি তালিকায় সংরক্ষণ করুন:

List<string> conditions = new List<string>();

if (condition1) conditions.Add("Col1=0");
//...
if (conditions.Any())
    Query += " WHERE " + string.Join(" AND ", conditions.ToArray());

24
ভাল সমাধান, তবে। ToArray()নেট 4 এর সাথে প্রয়োজনীয় নয় কারণ সেখানে একটি ওভারলোড রয়েছে যা কোনও গ্রহণ করে IEnumerable<string>
ফেরো

101
আমি সরবরাহ করি এমন সমস্ত এসকিউএল ইঞ্জেকশন সুযোগের জন্য আমি আগ্রহী।
asteri

12
@ জেফ আপনি যদি ক্লোজের মানগুলিতে কঠোর কোডিং না করে থাকেন তবে স্কেলপ্যারামিটারগুলির সাথে আপনার কেবল একটি দ্বিতীয় তালিকা থাকতে পারে। আপনাকে কেবল সেই তালিকাটি শর্ত তালিকার একই সাথে পপুলেশন করতে হবে এবং শেষে অ্যাড্রেঞ্জ (পরামিতিগুলি TToArray ()) কল করতে হবে।
স্কট চেম্বারলাইন

5
@ স্কট চেম্বারলাইন হ্যাঁ, আপনি ইনপুট স্ট্রিংগুলিকে তালিকায় রাখার আগে কেবল এড়াতে পারবেন। আমি বেশিরভাগই উত্তেজনাপূর্ণ রসাত্মক ব্যবহার করে একটি সম্ভাব্য আক্রমণ বিরুদ্ধে সতর্ক করেছিলাম।
asteri

4
@ জেফ এটি কেবল এসকিউএল ইঞ্জেকশনের জন্যই দুর্বল যদি শর্তাবলী ব্যবহারকারীর ইনপুট অন্তর্ভুক্ত করে (মূল উদাহরণটি তা নয়)
ডি স্ট্যানলে

85

একটি সমাধান হ'ল স্ট্রিংগুলি যুক্ত করে ম্যানুয়ালি প্রশ্নগুলি না লিখে। সত্তা ফ্রেমওয়ার্কের মতো আপনি একটি ওআরএম ব্যবহার করতে পারেন এবং লিনকিউতে সত্তা থেকে ভাষা এবং কাঠামো আপনাকে সরবরাহ করে এমন বৈশিষ্ট্যগুলি ব্যবহার করতে পারে:

using (var dbContext = new MyDbContext())
{
    IQueryable<Table1Item> query = dbContext.Table1;

    if (condition1)
    {
        query = query.Where(c => c.Col1 == 0);
    }
    if (condition2)
    {
        query = query.Where(c => c.Col2 == 1);
    }
    if (condition3)
    {
        query = query.Where(c => c.Col3 == 2);
    }   

    PrintResults(query);
}

@ প্রশ্নে আমি এই প্রশ্নটি বুঝতে পারি না। উভয়ই আলাদা ওআরএম।
কোডকাস্টার

দুঃখিত, আমি অন্যান্য ওআরএম-এর সাথে ড্যাপারের পারফরম্যান্সের তুলনা করতে অনুসন্ধান করেছিলাম এবং আমি গুগল দ্বারা এখানে এসেছি, তাই আমি ভেবেছিলাম উত্পন্ন PrintResults(query)উত্সত জিজ্ঞাসা হিসাবে ড্যাপারে ব্যবহার করব !!
vaheeds

@ ঠিক আছে, কিন্তু উত্তর বুঝতে না পারলে ডাউনভোটের নিশ্চয়তা পাওয়া যায় না। যদি তা আপনি হয়ে থাকেন, যা আপনার মন্তব্যের মত একই সময়ে ঘটনাক্রমে ঘটেছিল।
কোডকাস্টার

আপনার অধিকার, এটি একটি ভুল বোঝাবুঝি ছিল। আমি জটিল প্রশ্নের উপর লিনাক থেকে সত্তা খারাপ পারফরম্যান্স ভুগছি। আপনার অন্যান্য উত্তরের ভোট দিয়ে আমি নীচের ভোটটি ক্ষতিপূরণ করেছি;)
ওয়াহেডস

এটি প্রশ্নের উত্তর নয়
এইচজিমাচি

17

এই সাধারণ ক্ষেত্রে ওভারকিলের সামান্য বিট কিন্তু আমি অতীতে এর অনুরূপ কোড ব্যবহার করেছি।

একটি ফাংশন তৈরি করুন

string AddCondition(string clause, string appender, string condition)
{
    if (clause.Length <= 0)
    {
        return String.Format("WHERE {0}",condition);
    }
    return string.Format("{0} {1} {2}", clause, appender, condition);
}

এটি ব্যবহার করুন

string query = "SELECT * FROM Table1 {0}";
string whereClause = string.Empty;

if (condition 1)
    whereClause = AddCondition(whereClause, "AND", "Col=1");

if (condition 2)
    whereClause = AddCondition(whereClause, "AND", "Col2=2");

string finalQuery = String.Format(query, whereClause);

এইভাবে যদি কোনও শর্ত না পাওয়া যায় তবে আপনি কোয়েরিতে স্টেটমেন্ট বিবরণটি লোড করার জন্যও বারণ করবেন না এবং স্কাল সার্ভারটি জাঙ্কটি প্রক্রিয়াকরণের একটি মাইক্রো-সেকেন্ড সংরক্ষণ করবেন যেখানে ক্লাসটি যখন এসকিএল স্টেটমেন্টকে পার্স করবে তখন।


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

আপনাকে একটি মাইক্রো সেকেন্ডের গুরুত্ব সম্পর্কে আমাদের আলোকিত করার জন্য একটি ভোট দিয়েছে
ব্যবহারকারীর 451111

15

আরও একটি সমাধান রয়েছে, যা মার্জিত নাও হতে পারে, তবে কাজ করে এবং সমস্যার সমাধান করে:

String query = "SELECT * FROM Table1";
List<string> conditions = new List<string>();
// ... fill the conditions
string joiner = " WHERE ";
foreach (string condition in conditions) {
  query += joiner + condition;
  joiner = " AND "
}

এর জন্য:

  • খালি শর্তগুলির তালিকা, ফলাফলটি সহজভাবে হবে SELECT * FROM Table1 ,
  • একক শর্ত হবে SELECT * FROM Table1 WHERE cond1
  • প্রতিটি নিম্নলিখিত শর্ত অতিরিক্ত উত্পন্ন করবে AND condN

6
যে পাতার একটি আনত WHEREযদি কোন predicates হয়; এটি এড়াতে 1 = 1 নির্দিষ্টভাবে বিদ্যমান।
গাইউস

সুতরাং স্যুইচ String query = "SELECT * FROM Table1";এবং string jointer = " WHERE ";?
ব্রেন্ডন লং

@ ব্রেন্ডনলং তারপরে WHEREকি ANDশর্তগুলির মধ্যে স্থাপন করা যেতে পারে?
পেঙ্গুইন কোডার

@ পেঙ্গুইন কোডার একটি মন্তব্যে পুরো কোডটি দেখানো কঠিন। আমি বোঝাতে চাইছি string joinerলাইনটি প্রতিস্থাপন করুন string joiner = " WHERE ";এবং joiner = " AND ";লাইনটি একা রেখে দিন ।
ব্রেন্ডন লং

@ গাইউস আমি ধরে নিয়েছি কোডটিগুলি শূন্য নয়, তবে যেখানে জোয়ারে রাখা হয়েছে সেই কৌশলটি করা উচিত। মন্তব্যের জন্য ধন্যবাদ!
দারিউজ

11

এই জাতীয় কিছু করুন:

using (var command = connection.CreateCommand())
{
    command.CommandText = "SELECT * FROM Table1";

    var conditions = "";
    if (condition1)
    {    
        conditions += "Col1=@val1 AND ";
        command.AddParameter("val1", 1);
    }
    if (condition2)
    {    
        conditions += "Col2=@val2 AND ";
        command.AddParameter("val2", 1);
    }
    if (condition3)
    {    
        conditions += "Col3=@val3 AND ";
        command.AddParameter("val3", 1);
    }
    if (conditions != "")
        command.CommandText += " WHERE " + conditions.Remove(conditions.Length - 5);
}

এটি এসকিউএল ইঞ্জেকশন নিরাপদ এবং আইএমএইচও , এটি বেশ পরিষ্কার। Remove()কেবল গত সরিয়ে ফেলা হবে AND;

কোনও শর্ত নির্ধারণ না করা থাকলে, একটি সেট করা থাকলে বা একাধিক সেট করা থাকলে এটি উভয়ই কাজ করে।


1
আমি নিশ্চিত নই (নিজে সি # ব্যবহার করবেন না) তবে আমি বলব যে conditions != nullএটি সর্বদা true, যেমন আপনি এটি দিয়ে শুরু করেছিলেন ""(সি # না থাকলে "" == null)। এটি সম্ভবত একটি চেক হওয়া উচিত, যদি conditionsখালি না হয়… ;-)
সিগি

9

কেবল পিছনে দুটি লাইন যুক্ত করুন।

string Query="SELECT * FROM Table1 WHERE 1=1 ";
if (condition1) Query+="AND Col1=0 ";
if (condition2) Query+="AND Col2=1 ";
if (condition3) Query+="AND Col3=2 ";
Query.Replace("1=1 AND ", "");
Query.Replace(" WHERE 1=1 ", "");

যেমন

SELECT * FROM Table1 WHERE 1=1 AND Col1=0 AND Col2=1 AND Col3=2 

হয়ে যাবে

SELECT * FROM Table1 WHERE Col1=0 AND Col2=1 AND Col3=2 

যদিও

SELECT * FROM Table1 WHERE 1=1 

হয়ে যাবে

SELECT * FROM Table1

=====================================

এই সমাধানের ত্রুটি চিহ্নিত করার জন্য ধন্যবাদ:

"এটি কোনও কারণে শর্তগুলির একটিতে" 1 = 1 এবং "বা" যেখানে 1 = 1 "লেখাটি অন্তর্ভুক্ত করতে পারে তা যদি এই ক্যোয়ারীটি ভেঙে ফেলতে পারে the উদাহরণস্বরূপ কলামে এই পাঠ্য রয়েছে। সম্ভবত এটি আপনার ক্ষেত্রে সমস্যা নয় তবে আপনার এটি মনে রাখা উচিত ... "

এই সমস্যা থেকে পরিত্রাণ পেতে, আমাদের "প্রধান" যেখানে 1 = 1 এবং subquery থেকে পৃথক করা প্রয়োজন, যা সহজ:

কেবলমাত্র "প্রধান" যেখানে বিশেষ বিশেষ করুন: আমি একটি "$" চিহ্ন যুক্ত করব

string Query="SELECT * FROM Table1 WHERE$ 1=1 ";
if (condition1) Query+="AND Col1=0 ";
if (condition2) Query+="AND Col2=1 ";
if (condition3) Query+="AND Col3=2 ";

তারপরে এখনও দুটি লাইন যুক্ত করুন:

Query.Replace("WHERE$ 1=1 AND ", "WHERE ");
Query.Replace(" WHERE$ 1=1 ", "");

1
এটি কোয়েরিকে ভেঙে দিতে পারে যদি কোনও কারণে শর্তের একটিতে পাঠ্য "1=1 AND "বা থাকে " WHERE 1=1 "। এটির ক্ষেত্রে যদি শর্তটিতে একটি সাবকিউরি থাকে বা কোনও কলামে এই পাঠ্য রয়েছে কিনা তা পরীক্ষা করে দেখার চেষ্টা করে তবে এটি হতে পারে। হতে পারে এটি আপনার ক্ষেত্রে কোনও সমস্যা নয় তবে আপনার এটি মনে রাখা উচিত ...
siegi

8

এটা ব্যবহার কর:

string Query="SELECT * FROM Table1 WHERE ";
string QuerySub;
if (condition1) QuerySub+="AND Col1=0 ";
if (condition2) QuerySub+="AND Col2=1 ";
if (condition3) QuerySub+="AND Col3=2 ";

if (QuerySub.StartsWith("AND"))
    QuerySub = QuerySub.TrimStart("AND".ToCharArray());

Query = Query + QuerySub;

if (Query.EndsWith("WHERE "))
    Query = Query.TrimEnd("WHERE ".ToCharArray());

এই উত্তরটি কার্যকর হবে, এবং এটিতে আসলে কোনও ভুল নেই, তবে আমি মনে করি না এটি মূল প্রশ্নের চেয়ে আরও পরিষ্কার এবং সহজ। স্ট্রিং-সন্ধান QuerySubআমার মতে where 1=1হ্যাক ব্যবহারের চেয়ে ভাল বা খারাপ নয় । তবে এটি একটি চিন্তাশীল অবদান।
ক্যাটফুড

3
সেখানে একটা ভুল ছিল. সংশোধন করেছেন শর্তগুলির একটিও উপস্থিত না থাকলে আমার ক্যোয়ারী বোমা ফাটিয়ে দিত :- পি তবুও আমাকে অবশ্যই বলতে হবে যে আহমেদ বা কোডকাস্টার আমার কাছে সর্বোত্তম সমাধান। আমি কেবল আপনাদের জন্য একটি বিকল্প উপস্থাপন করেছি!
অঙ্কুশুম

সাধারণভাবে এখনও এটি ভুল। মনে করুন এটি ছিল ... FROM SOMETABLE WHERE ; তাহলে TrimEndপ্রকৃতপক্ষে এটি এটিকে হ্রাস করবে ... FROM SOMETABL। যদি এটি আসলে একটি হয়ে থাকে StringBuilder(যা আপনার যদি এই স্ট্রিং ম্যানিপুলেশন বা আরও কিছু সম্পর্কে থাকতে পারে) আপনি ঠিক করতে পারেন Query.Length -= "WHERE ".Length;
মার্ক হার্ট

চিহ্নিত করুন, এটি কাজ করে। আমি অনেক প্রকল্পে এটি চেষ্টা করেছি। এটি ব্যবহার করে দেখুন এবং আপনি এটি দেখতে পাবেন!
অঙ্কুশান

8
জাহান্নাম হিসাবে কুরুচিপূর্ণ :) প্লাস যদি আমি সঠিকভাবে গণনা করি তবে এটি 7 টি পর্যন্ত স্ট্রিং তৈরি করতে পারে
পাইওটর পেরাক

5

একটি বিদ্যমান কোয়েরি বিল্ডার ব্যবহার করছেন না কেন? স্কেল কাটার মতো কিছু

এটি জটিল যেখানে শর্ত, যোগ দেয় এবং subqueries সমর্থন করে।

var query = new Query("Users").Where("Score", ">", 100).OrderByDesc("Score").Limit(100);

if(onlyActive)
{
   query.Where("Status", "active")
}

// or you can use the when statement

query.When(onlyActive, q => q.Where("Status", "active"))

এটি এসকিএল সার্ভার, মাইএসকিউএল এবং পোস্টগ্রেএসকিএল এর সাথে কাজ করে।


4

আপনি যা জিজ্ঞাসা করতে চাইছেন তার দ্রুততম আক্ষরিক সমাধান হ'ল এটি:

string Query="SELECT * FROM Table1";
string Conditions = "";

if (condition1) Conditions+="AND Col1=0 ";
if (condition2) Conditions+="AND Col2=1 ";
if (condition3) Conditions+="AND Col3=2 ";

if (Conditions.Length > 0) 
  Query+=" WHERE " + Conditions.Substring(3);

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

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


4

এটি যদি এসকিউএল সার্ভার হয় তবে আপনি এই কোডটি আরও পরিষ্কার করতে পারেন।

এটি প্যারামিটারগুলির একটি জ্ঞাত সংখ্যাও ধরে নিয়েছে, যখন আমি সম্ভাবনাগুলি সম্পর্কে চিন্তা করি তখন এটি একটি দরিদ্র ধারণা হতে পারে।

সি # তে, আপনি ব্যবহার করবেন:

using (SqlConnection conn = new SqlConnection("connection string"))
{
    conn.Open();
    SqlCommand command = new SqlCommand()
    {
        CommandText = "dbo.sample_proc",
        Connection = conn,
        CommandType = CommandType.StoredProcedure
    };

    if (condition1)
        command.Parameters.Add(new SqlParameter("Condition1", condition1Value));
    if (condition2)
        command.Parameters.Add(new SqlParameter("Condition2", condition2Value));
    if (condition3)
        command.Parameters.Add(new SqlParameter("Condition3", condition3Value));

    IDataReader reader = command.ExecuteReader();

    while(reader.Read())
    {
    }

    conn.Close();
}

এবং তারপরে এসকিউএল দিকে:

CREATE PROCEDURE dbo.sample_proc
(
    --using varchar(50) generically
    -- "= NULL" makes them all optional parameters
    @Condition1 varchar(50) = NULL
    @Condition2 varchar(50) = NULL
    @Condition3 varchar(50) = NULL
)
AS
BEGIN
    /*
    check that the value of the parameter 
    matches the related column or that the 
    parameter value was not specified.  This
    works as long as you are not querying for 
    a specific column to be null.*/
    SELECT *
    FROM SampleTable
    WHERE (Col1 = @Condition1 OR @Condition1 IS NULL)
    AND   (Col2 = @Condition2 OR @Condition2 IS NULL)
    AND   (Col3 = @Condition3 OR @Condition3 IS NULL)
    OPTION (RECOMPILE)
    --OPTION(RECOMPILE) forces the query plan to remain effectively uncached
END

আপনার কলামগুলি একটি অভিব্যক্তির ভিতরে লুকিয়ে রাখলে সূচিপত্রের ব্যবহার রোধ করা যায় এবং এই কৌশলটি এখানে এই কারণেই নিরুৎসাহিত করা হয় ।
বিবিসিমোনববি

এটি একটি আকর্ষণীয় অনুসন্ধান। এই তথ্যের জন্য ধন্যবাদ। আপডেট হবে
mckeejm

3

শর্তের উপর নির্ভর করে কোয়েরিতে বুলিয়ান যুক্তি ব্যবহার করা সম্ভব হতে পারে। এটার মতো কিছু :

string Query="SELECT * FROM Table1  " +
             "WHERE (condition1 = @test1 AND Col1=0) "+
             "AND (condition2 = @test2 AND Col2=1) "+
             "AND (condition3 = @test3 AND Col3=2) ";

3

আমি স্ট্রিংবিল্ডারের সাবলীল ইন্টারফেস পছন্দ করি, তাই আমি কিছু এক্সটেনশনমেড তৈরি করেছি।

var query = new StringBuilder()
    .AppendLine("SELECT * FROM products")
    .AppendWhereIf(!String.IsNullOrEmpty(name), "name LIKE @name")
    .AppendWhereIf(category.HasValue, "category = @category")
    .AppendWhere("Deleted = @deleted")
    .ToString();

var p_name = GetParameter("@name", name);
var p_category = GetParameter("@category", category);
var p_deleted = GetParameter("@deleted", false);
var result = ExecuteDataTable(query, p_name, p_category, p_deleted);


// in a seperate static class for extensionmethods
public StringBuilder AppendLineIf(this StringBuilder sb, bool condition, string value)
{
    if(condition)
        sb.AppendLine(value);
    return sb;
}

public StringBuilder AppendWhereIf(this StringBuilder sb, bool condition, string value)
{
    if (condition)
        sb.AppendLineIf(condition, sb.HasWhere() ? " AND " : " WHERE " + value);
    return sb;
}

public StringBuilder AppendWhere(this StringBuilder sb, string value)
{
    sb.AppendWhereIf(true, value);
    return sb;
}

public bool HasWhere(this StringBuilder sb)
{
    var seperator = new string [] { Environment.NewLine };
    var lines = sb.ToString().Split(seperator, StringSplitOptions.None);
    return lines.Count > 0 && lines[lines.Count - 1].Contains("where", StringComparison.InvariantCultureIgnoreCase);
}

// http://stackoverflow.com/a/4217362/98491
public static bool Contains(this string source, string toCheck, StringComparison comp)
{
    return source.IndexOf(toCheck, comp) >= 0;
}

2

আইএমএইচও, আমি মনে করি যে আপনার পদ্ধতিটি ভুল:

স্ট্রাক্টকে স্ট্রাক্ট করে ডাটাবেস অনুসন্ধান করা ভাল ধারণা না ( এসকিউএল ইঞ্জেকশনের ঝুঁকি এবং কোডটি আপনি অন্য কোথাও কিছু পরিবর্তন করলে সহজেই ভেঙে যেতে পারে)।

আপনি একটি ব্যবহার করতে পারেন ORM (আমি ব্যবহার NHibernate ) অথবা অন্তত ব্যবহার এSqlCommand.Parameters

আপনি যদি পুরোপুরি স্ট্রিং কনটেনটেশন ব্যবহার করতে চান তবে আমি একটি ব্যবহার করব StringBuilder(এটি স্ট্রিং কনটেনটেশনের জন্য সঠিক বিষয়):

var query = new StringBuilder("SELECT * FROM Table1 WHERE");
int qLength = query.Length;//if you don't want to count :D
if (Condition1) query.Append(" Col1=0 AND");
if (Condition2) query.Append(" Col2=0 AND");
....
//if no condition remove WHERE or AND from query
query.Length -= query.Length == qLength ? 6 : 4;

শেষ চিন্তা হিসাবে, Where 1=1সত্যিই কুৎসিত কিন্তু এসকিউএল সার্ভার যাইহোক এটি এটিকে অপ্টিমাইজ করবে।


SELECT * FROM Table1 WHERE AND Col1=0সঠিক বলে মনে হচ্ছে না, যা পুরো বিষয়টি WHERE 1=1
মরমেগিল

2

ড্যাপার স্কেলবিল্ডার একটি বেশ ভাল বিকল্প। এটি স্ট্যাকওভারফ্লোতে উত্পাদনে ব্যবহৃত হয়।

এটি সম্পর্কে স্যাম ব্লগ এন্ট্রি পড়ুন ।

যতদূর আমি জানি, এটি কোনও নুগেট প্যাকেজের অংশ নয়, সুতরাং আপনার কোডটির কোডটি আপনার প্রকল্পে অনুলিপি করতে হবে বা ডাপার উত্সটি ডাউনলোড করতে হবে এবং স্কেলবিল্ডার প্রকল্পটি তৈরি করতে হবে। যে কোনও উপায়ে, আপনাকে DynamicParametersক্লাসের জন্য ডাপারও উল্লেখ করতে হবে ।


1
আমি মনে করি না যে ডিপারের স্কেলবিল্ডার সেই প্যাকেজে অন্তর্ভুক্ত রয়েছে।
রনি ওভারবি

1

সঞ্চিত পদ্ধতিতে ডায়নামিক এসকিউএল তৈরি করার সময় আমি ওরাকলে এটি সর্বদা ব্যবহৃত দেখি । আমি ডেটা ইস্যুগুলি অন্বেষণ করার সাথে সাথে এটি কেবল ডেটা বিভিন্ন ফিল্টারের মধ্যে দ্রুত পরিবর্তন করার জন্য প্রশ্নগুলিতে ব্যবহার করি ... কেবল কোনও শর্তে মন্তব্য করুন বা সহজেই এটিকে আবার যুক্ত করুন।

আমি মনে করি এটি বেশ সাধারণ এবং আপনার কোডটি পর্যালোচনা করে এমন কাউকে বোঝার পক্ষে যথেষ্ট সহজ।


1
public static class Ext
{
    public static string addCondition(this string str, bool condition, string statement)
    {
        if (!condition)
            return str;

        return str + (!str.Contains(" WHERE ") ? " WHERE " : " ") + statement;
    }

    public static string cleanCondition(this string str)
    {
        if (!str.Contains(" WHERE "))
            return str;

        return str.Replace(" WHERE AND ", " WHERE ").Replace(" WHERE OR ", " WHERE ");
    }
}

এক্সটেনশন পদ্ধতির সাথে উপলব্ধি।

    static void Main(string[] args)
    {
        string Query = "SELECT * FROM Table1";

        Query = Query.addCondition(true == false, "AND Column1 = 5")
            .addCondition(18 > 17, "AND Column2 = 7")
            .addCondition(42 == 1, "OR Column3 IN (5, 7, 9)")
            .addCondition(5 % 1 > 1 - 4, "AND Column4 = 67")
            .addCondition(Object.Equals(5, 5), "OR Column5 >= 0")
            .cleanCondition();

        Console.WriteLine(Query);
    }

শস্যের বিরুদ্ধে চলছে!
রনি ওভারবি

আমার execuse? ডু মানে কি?
ম্যাক্সিম ঝুকভ

0

stringফাংশন ব্যবহার করে আপনি এটি এইভাবে করতে পারেন:

string Query = "select * from Table1";

if (condition1) WhereClause += " Col1 = @param1 AND "; // <---- put conditional operator at the end
if (condition2) WhereClause += " Col1 = @param2 OR ";

WhereClause = WhereClause.Trim();

if (!string.IsNullOrEmpty(WhereClause))
    Query = Query + " WHERE " + WhereClause.Remove(WhereClause.LastIndexOf(" "));
// else
// no condition meets the criteria leave the QUERY without a WHERE clause  

আমি শর্তসাপেক্ষ উপাদানটি শেষ পর্যন্ত অপসারণ করা ব্যক্তিগতভাবে সহজ বোধ করি, কারণ এর অবস্থান অনুমান করা সহজ।


0

আমি এমন একটি সমাধানের কথা ভেবেছিলাম যা ভাল, সম্ভবত আরও কিছুটা পাঠযোগ্য:

string query = String.Format("SELECT * FROM Table1 WHERE "
                             + "Col1 = {0} AND "
                             + "Col2 = {1} AND "
                             + "Col3 = {2}",
                            (!condition1 ? "Col1" : "0"),
                            (!condition2 ? "Col2" : "1"),
                            (!condition3 ? "Col3" : "2"));

আমি ঠিক নিশ্চিত নই যে এসকিউএল ইন্টারপ্রেটারও Col1 = Col1শর্তটি অপ্টিমাইজ করবে ( condition1মিথ্যা হলে মুদ্রিত )।


0

এখানে আরও মার্জিত উপায়:

    private string BuildQuery()
    {
        string MethodResult = "";
        try
        {
            StringBuilder sb = new StringBuilder();

            sb.Append("SELECT * FROM Table1");

            List<string> Clauses = new List<string>();

            Clauses.Add("Col1 = 0");
            Clauses.Add("Col2 = 1");
            Clauses.Add("Col3 = 2");

            bool FirstPass = true;

            if(Clauses != null && Clauses.Count > 0)
            {
                foreach(string Clause in Clauses)
                {
                    if (FirstPass)
                    {
                        sb.Append(" WHERE ");

                        FirstPass = false;

                    }
                    else
                    {
                        sb.Append(" AND ");

                    }

                    sb.Append(Clause);

                }

            }

            MethodResult = sb.ToString();

        }
        catch //(Exception ex)
        {
            //ex.HandleException()
        }
        return MethodResult;
    }

0

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

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

select * from table1
where (col1 = @param1 or @param1 is null)
and (col2 = @param2 or @param2 is null)
and (col3 = @param3 or @param3 is null)
OPTION (RECOMPILE)

কোয়েরি ফার্স্ট আপনাকে সি # নুলকে ডিবি করতে নল দেয়, সুতরাং আপনি যখন উপযুক্ত হবে তখন নাল দিয়ে এক্সিকিউট () পদ্ধতিটি কল করুন এবং এটি সব ঠিক কাজ করে। <কপিরাইট> সি # ডেভেলস এসকিউএল এ স্টাফ করতে এতটা অনিচ্ছুক, এমনকি এটি সহজ হলেও। মাইন্ড বগলস </


0

দীর্ঘতর ফিল্টারিং পদক্ষেপের জন্য স্ট্রিংবিল্ডার হিসাবে অনেকের বক্তব্যই ভাল approach

আপনার ক্ষেত্রে আমি সাথে যেতে হবে:

StringBuilder sql = new StringBuilder();

if (condition1) 
    sql.Append("AND Col1=0 ");
if (condition2) 
    sql.Append("AND Col2=1 ");
if (condition3) 
    sql.Append("AND Col3=2 ");

string Query = "SELECT * FROM Table1 ";
if(sql.Length > 0)
 Query += string.Concat("WHERE ", sql.ToString().Substring(4)); //avoid first 4 chars, which is the 1st "AND "

0

সংক্ষিপ্ত, মার্জিত এবং মিষ্টি, নীচের চিত্রে দেখানো হয়েছে।

এখানে চিত্র বর্ণনা লিখুন

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