আমি কি মাইএসকিউএলে প্যারামিটার দিয়ে ভিউ তৈরি করতে পারি?


94

আমার মতামত আছে:

CREATE VIEW MyView AS
   SELECT Column FROM Table WHERE Value = 2;

আমি এটিকে আরও জেনেরিক করে তুলতে চাই, এর অর্থ ২ টি ভেরিয়েবলে পরিবর্তন করা। আমি এটি চেষ্টা করেছি:

CREATE VIEW MyView AS
   SELECT Column FROM Table WHERE Value = @MyVariable;

তবে মাইএসকিউএল এটির অনুমতি দেয় না।

আমি একটি কুরুচিপূর্ণ কাজ পেয়েছি:

CREATE FUNCTION GetMyVariable() RETURNS INTEGER DETERMINISTIC NO SQL
BEGIN RETURN @MyVariable; END|

এবং তারপরে ভিউটি হ'ল:

CREATE VIEW MyView AS
   SELECT Column FROM Table WHERE Value = GetMyVariable();

তবে এটি দেখতে আসলেই কৃপণ, এবং ব্যবহারটিও কৃপণ - প্রতিটি ভিউয়ের ব্যবহারের আগে আমাকে @ মাই ভার্ভেয়েবল সেট করতে হবে।

এমন কোনও সমাধান আছে যা আমি এই জাতীয়ভাবে ব্যবহার করতে পারি:

SELECT Column FROM MyView(2) WHERE (...)

কংক্রিট পরিস্থিতি নিম্নরূপ: অস্বীকৃত অনুরোধ সম্পর্কে আমার কাছে একটি সারণী তথ্য রয়েছে:

CREATE TABLE Denial
(
    Id INTEGER UNSIGNED AUTO_INCREMENT,
        PRIMARY KEY(Id),
    DateTime DATETIME NOT NULL,
    FeatureId MEDIUMINT UNSIGNED NOT NULL,
        FOREIGN KEY (FeatureId)
            REFERENCES Feature (Id)
            ON UPDATE CASCADE ON DELETE RESTRICT,
    UserHostId MEDIUMINT UNSIGNED NOT NULL,
        FOREIGN KEY (UserHostId)
            REFERENCES UserHost (Id)
            ON UPDATE CASCADE ON DELETE RESTRICT,
    Multiplicity MEDIUMINT UNSIGNED NOT NULL DEFAULT 1,
    UNIQUE INDEX DenialIndex (FeatureId, DateTime, UserHostId)
) ENGINE = InnoDB;

একটি বহুবৃত্তি হ'ল একই সেকেন্ডে রেকর্ড করা অভিন্ন অনুরোধের একটি সংখ্যা। আমি অস্বীকারের একটি তালিকা প্রদর্শন করতে চাই, তবে কখনও কখনও, যখন অ্যাপ্লিকেশনটি অস্বীকার হয়ে যায়, এটি নিশ্চিত করার জন্য এটি কয়েকবার চেষ্টা করে। সুতরাং সাধারণত, একই ব্যবহারকারী যখন কয়েক সেকেন্ডে একই বৈশিষ্ট্যটিতে 3 বার অস্বীকৃতি পান তখন এটি আসলে একটি অস্বীকার। এই অনুরোধটি পূরণ করতে যদি আমাদের আরও একটি সংস্থান থাকে তবে পরবর্তী দুটি অস্বীকৃতি ঘটবে না। সুতরাং আমরা প্রতিবেদনে অস্বীকারগুলি গোষ্ঠী করতে চাই যাতে ব্যবহারকারীকে টাইমস্প্যানটি নির্দিষ্ট করতে দেয় যাতে অস্বীকারগুলি গোষ্ঠীভুক্ত করা উচিত। উদাহরণস্বরূপ, যদি টাইমস্ট্যাম্পগুলিতে আমাদের অস্বীকার (বৈশিষ্ট্য 1 তে ব্যবহারকারী 1 এর জন্য) থাকে: 1,2,24,26,27,45 এবং ব্যবহারকারী 4 টি সেকেন্ডের চেয়ে একে অপরের নিকটে থাকা অস্বীকৃতিগুলি গ্রুপ করতে চায়, তার এই জাতীয় কিছু পাওয়া উচিত: 1 (এক্স 2), 24 (এক্স 3), 45 (এক্স 1)। আমরা ধরে নিতে পারি, প্রকৃত অস্বীকারগুলির মধ্যে ফাঁকগুলি সদৃশগুলির মধ্যে অনেক বড়।

CREATE FUNCTION GetDenialMergingTime()
    RETURNS INTEGER UNSIGNED
    DETERMINISTIC NO SQL
BEGIN
    IF ISNULL(@DenialMergingTime) THEN
        RETURN 0;
    ELSE
        RETURN @DenialMergingTime;
    END IF;
END|

CREATE VIEW MergedDenialsViewHelper AS
    SELECT MIN(Second.DateTime) AS GroupTime,
        First.FeatureId,
        First.UserHostId,
        SUM(Second.Multiplicity) AS MultiplicitySum
    FROM Denial AS First 
        JOIN Denial AS Second 
            ON First.FeatureId = Second.FeatureId
                AND First.UserHostId = Second.UserHostId
                AND First.DateTime >= Second.DateTime
                AND First.DateTime - Second.DateTime < GetDenialMergingTime()
    GROUP BY First.DateTime, First.FeatureId, First.UserHostId, First.Licenses;

CREATE VIEW MergedDenials AS
    SELECT GroupTime, 
        FeatureId,
        UserHostId, 
        MAX(MultiplicitySum) AS MultiplicitySum
    FROM MergedDenialsViewHelper
    GROUP BY GroupTime, FeatureId, UserHostId;

তারপরে 3 এবং 4 বৈশিষ্ট্যগুলিতে 1 এবং 2 ব্যবহারকারীর কাছ থেকে অস্বীকারগুলি দেখাতে প্রতি 5 সেকেন্ডে একীভূত করা আপনাকে যা করতে হবে তা হ'ল:

SET @DenialMergingTime := 5;
SELECT GroupTime, FeatureId, UserHostId, MultiplicitySum FROM MergedDenials WHERE UserHostId IN (1, 2) AND FeatureId IN (3, 4);

আমি দৃশ্যটি ব্যবহার করি কারণ এর মধ্যে ডেটা ফিল্টার করা সহজ এবং এটি jQuery গ্রিডে স্পষ্টভাবে ব্যবহার করা, স্বয়ংক্রিয়ভাবে অর্ডার করা, রেকর্ডের সংখ্যা সীমাবদ্ধ করা ইত্যাদি and

তবে এটি কেবল একটি কুরুচিপূর্ণ কাজ। এটি করার কোনও সঠিক উপায় আছে কি?

উত্তর:


164

আসলে আপনি যদি ফানক তৈরি করেন:

create function p1() returns INTEGER DETERMINISTIC NO SQL return @p1;

এবং দেখুন:

create view h_parm as
select * from sw_hardware_big where unit_id = p1() ;

তারপরে আপনি একটি প্যারামিটার দিয়ে একটি ভিউ কল করতে পারেন:

select s.* from (select @p1:=12 p) parm , h_parm s;

আমি আসা করি এটা সাহায্য করবে.


31
বাহ, এটি এসকিউএল-এ আমি দেখেছি এমন সবচেয়ে হ্যাকী জিনিসগুলির মধ্যে একটি;) তবে এটি আমি যা করতে চাইছিলাম ঠিক তা-ই।
ssobczak

4
এই কৌশলটি কোনও সঞ্চিত পদ্ধতির মধ্যে একটি ভিউ তৈরি করার সময় কাজ করে, যখন তৈরি করা ভিউ স্টোরেজ পদ্ধতিতে পাস করা কোনও ভারচারের উপর নির্ভরশীল। এই ক্ষেত্রে, আমাকে 'p @ = 1 সেট করতে হয়েছিল;' ভিউ তৈরি করার জন্য কল করার আগে লাইনে।
ক্লেটন স্ট্যানলি

4
যদি বেশ কয়েকটি ডাটাবেস ভাড়াটিয়রা এই কোডটি একযোগে কল করে তবে সমস্যাগুলির (কোনও ভাড়াটে ডেটা মিক্সআপ) সম্ভাবনা রয়েছে?
গ্রুবার

4
@ মিআর_আর_আমস_ডি উদ্ভূত টেবিলটির একটি উপাম প্রয়োজন। আপনি যা
খুশি

4
ভেরিয়েবল পি 1 এর পরে এর মান ধরে রাখে, সুতরাং আপনি যদি প্যারামিটারটি না দিয়ে আবার ভিউটি ব্যবহার করেন তবে এটি পূর্বের পাস হওয়া ব্যবহার করবে - যা সম্ভবত বিভ্রান্তিকর! এটি এর ব্যবহারের পরে আপনি এটি "সাফাই" করতে পারেন: এস থেকে নির্বাচন করুন from (ধরে নেওয়া -1 এই উদ্দেশ্যে একটি অবৈধ মান)
বুভিনজে

22
CREATE VIEW MyView AS
   SELECT Column, Value FROM Table;


SELECT Column FROM MyView WHERE Value = 1;

মাইএসকিউএল-তে সঠিক সমাধান, অন্য কিছু এসকিউএল আপনাকে ভিউগুলি আরও সঠিকভাবে সংজ্ঞায়িত করতে দেয়।

দ্রষ্টব্য: ভিউটি খুব জটিল না হলে মাইএসকিউএল এটি ঠিকঠাক করে দেবে।


4
আমার ক্ষেত্রে যেখানে অংশটি আমি প্যারামিটারটি ব্যবহার করতে চাই সেগুলি নিস্টেড সিলেক্ট করা হয়েছে, সুতরাং এটি দেখার বাইরে থেকে ফিল্টার করা অসম্ভব।
ssobczak

প্রকৃতপক্ষে নেস্টেড নির্বাচিতদের দর্শনগুলিতে অনুমোদিত নয়, তবে আমি এগুলিকে দুটি দলে ভাগ করেছি। ভি 1 ফিল্টার করে এবং ডেটা সংগ্রহ করে এবং ভি 1 এর উপরে ভি 2 থাকে। আমি ভি 1 থেকে এর বাইরে ডেটা ফিল্টার করতে পারি না (ভি 2 এ), বাইরের বাইরে এগুলি একত্রিত হিসাবে দৃশ্যমান।
ssobczak

4
তারপরে, আপনার যদি সঠিক নিয়ন্ত্রণের প্রয়োজন হয় তবে প্রতিবার পুরো ক্যোয়ারীটি তৈরি করুন বা সঞ্চিত পদ্ধতিতে কোয়েরিটি তৈরি করুন all দৃশ্য হিসাবে সংরক্ষণ করা অর্থহীন বলে মনে হয়। যদিও আপনি কোয়েরি পোস্ট করলেও আপনি যে কাউকে অর্জন করার চেষ্টা করছেন তা ভিন্ন / উন্নত রুটের পরামর্শ দিতে সক্ষম হতে পারে।
MindStalker

আমি এটি না করতে চেয়েছিলাম, কারণ এটি আমার সহজ প্রশ্নটিকে জটিল করে তুলবে, তবে আপনি যদি মনে করেন এটি কার্যকর হতে পারে তবে আমি চেষ্টা করব।
ssobczak

এই ফর্ম্যাটটি আপনাকে প্যারামিটারের উপর নির্ভর করে ফলাফল সেট বা টেবিলের নাম পরিবর্তন করতে দেয় না
এমএমইএল

1

আমি পূর্বে একটি পৃথক কাজ নিয়ে এসেছি যা সঞ্চিত পদ্ধতি ব্যবহার করে না, তবে পরিবর্তে একটি প্যারামিটার টেবিল এবং কিছু সংযোগ_আইডি () যাদু ব্যবহার করে।

সম্পাদনা (মন্তব্য থেকে অনুলিপি করা)

একটি টেবিল তৈরি করুন যার মধ্যে একটি কলাম রয়েছে connection_id(এটি একটি বিগিন্ট করুন) contains দেখার জন্য পরামিতিগুলির জন্য সেই সারণীতে কলামগুলি রাখুন। উপর একটি প্রাথমিক কী রাখুন connection_id। প্যারামিটার সারণীতে প্রতিস্থাপন করুন এবং CONNECTION_ID()সংযোগ_আইডি মানটি পপুলেট করতে ব্যবহার করুন । ভিউতে প্যারামিটার টেবিলটিতে একটি ক্রস জয়েন ব্যবহার করুন এবং রাখুন WHERE param_table.connection_id = CONNECTION_ID()। এটি প্যারামিটার টেবিল থেকে কেবল একটি সারি দিয়ে যোগ ক্রস করবে যা আপনি চান। তারপরে আপনি যেখানে অন্য কলামগুলি উদাহরণের উদাহরণ হিসাবে ব্যবহার করতে পারেন orders.order_id = param_table.order_id


4
কোনটি? আমাদের আরও কিছু বলুন।
মার্জপাওয়ার

4
সংযোগ_id নামে একটি কলামযুক্ত একটি সারণী তৈরি করুন (এটি একটি বিগিন্ট করুন)। দেখার জন্য পরামিতিগুলির জন্য সেই সারণীতে কলামগুলি রাখুন। সংযোগ_আইডিতে একটি প্রাথমিক কী রাখুন। প্যারামিটার সারণীতে প্রতিস্থাপন করুন এবং সংযোগ_আইডি মানটি তৈরি করতে CONNECTION_ID () ব্যবহার করুন। ভিউতে প্যারামিটার টেবিলটিতে একটি ক্রস জয়েন ব্যবহার করুন এবং WHERE param_table.connection_id = CONNECTION_ID () দিন। এটি প্যারামিটার টেবিল থেকে কেবল একটি সারি দিয়ে যোগ ক্রস করবে যা আপনি চান। তারপরে আপনি যেখানে অন্য কলামগুলি যেখানে ক্লাসের উদাহরণ হিসাবে উদাহরণগুলি অর্ডার করতে পারেন যেখানে অর্ডার.অর্ডার_আইডি = প্যারাম_ট্যাবল.অর্ডার_আইডি ব্যবহার করতে পারেন।
জাস্টিন সোয়ানহার্ট

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