আমরা কি এসকিউএল-এর একটি ভিউতে প্যারামিটারগুলি পাস করতে পারি?


138

আমরা কি মাইক্রোসফ্ট এসকিউএল সার্ভারে একটি ভিউতে একটি প্যারামিটারটি পাস করতে পারি?

আমি create viewনিম্নলিখিত পদ্ধতিতে চেষ্টা করেছি , কিন্তু এটি কার্যকর হয় না:

create or replace view v_emp(eno number) as select * from emp where emp_id=&eno;

একটি ভিউ একটি নির্বাচিত ক্যোয়ারির একটি সঞ্চিত স্কয়ার পাঠ্য। পরামিতিগুলি আলোচনার বাইরে। যখন আপনার সঞ্চিত ক্যোয়ারী আপনি যে কলামটি ফিল্টার করতে চান সেখানে ফিরে আসে, আপনি কলিং ক্যোয়ারিতে এটি করতে পারেন। উদাহরণস্বরূপ "V_emp থেকে নির্বাচন করুন * কোথায় এমপিআইডি =?"
এপিকিউরিস্ট

2
@ ইপিকিউরিস্ট Parameters are out of the discussionখুব সাহসী বক্তব্য। Counterexample
Lukasz Szozda

উত্তর:


132

ইতিমধ্যে বলেছি আপনি পারবেন না।

একটি সম্ভাব্য সমাধান হ'ল কোনও সঞ্চিত ফাংশন প্রয়োগ করা, যেমন:

CREATE FUNCTION v_emp (@pintEno INT)
RETURNS TABLE
AS
RETURN
   SELECT * FROM emp WHERE emp_id=@pintEno;

এটি আপনাকে এটির সাথে একটি সাধারণ দর্শন হিসাবে ব্যবহার করতে দেয়:

SELECT * FROM v_emp(10)

এই এবং একটি দর্শনের মধ্যে ব্যবহারিক পার্থক্য কি? আপনি কেবল এই ফাংশনটি অ্যাক্সেস করতে ব্যবহারকারীর অনুমতিগুলি বরাদ্দ করতে পারেন?
মাইকমুরকো

মাইএসকিউএল এ আপনি একটি সঞ্চিত পদ্ধতি লিখেন এবং পদ্ধতিতে শেষ বিবৃতিটি আপনি ফিরে আসতে চান এমন রেজাল্ট হতে পারে।
বোবোবো

জাভা জেডিবিসি কোড থেকে কোন সমস্যা ছাড়াই আমরা কি এই অনুরোধটি ব্যবহার করতে পারি?
মওনাইম

@ মাইকমুরকো এর একটি গুরুত্বপূর্ণ পার্থক্য হ'ল কোনও দৃশ্যের কলামগুলি সম্পর্কে স্কিমা / মেটাডেটা যদি এটির মত হয় তবে এটি অনুসন্ধান করা যেতে পারে। যদি এটি সঞ্চিত প্রোক বা কোনও ফাংশন হয়, তবে আমার ধারণা ডেটাবেসগুলি আপনাকে সেই তথ্য দিতে সক্ষম না হতে পারে।
নাগু

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

35

আপনি যা দুর্ভাগ্যজনকভাবে চান তা অর্জন করার জন্য দুটি উপায় রয়েছে কোনও দৃশ্য ব্যবহার করেও করা যায় না।

আপনি হয় একটি সারণী মূল্যবান ব্যবহারকারীর সংজ্ঞায়িত ফাংশন তৈরি করতে পারেন যা আপনার পছন্দমতো প্যারামিটার নেয় এবং একটি কোয়েরির ফলাফল দেয়

অথবা আপনি একই জিনিসটি বেশ কিছু করতে পারেন তবে ব্যবহারকারীর সংজ্ঞায়িত ফাংশনের পরিবর্তে একটি সঞ্চিত পদ্ধতি তৈরি করতে পারেন।

উদাহরণ স্বরূপ

সঞ্চিত পদ্ধতিটি দেখতে ভালো লাগবে

CREATE PROCEDURE s_emp
(
    @enoNumber INT
) 
AS 
SELECT
    * 
FROM
    emp 
WHERE 
    emp_id=@enoNumber

অথবা ব্যবহারকারীর সংজ্ঞায়িত ফাংশনটি দেখতে হবে

CREATE FUNCTION u_emp
(   
    @enoNumber INT
)
RETURNS TABLE 
AS
RETURN 
(
    SELECT    
        * 
    FROM    
        emp 
    WHERE     
        emp_id=@enoNumber
)

কেবল মনে রাখবেন যে আপনি এসপি বিকল্পটি SELECTসহজে ব্যবহার করতে পারবেন না : আরও পড়ুন
সাস্তন করুন

13

না আপনি পারবেন না, যেমন ম্লাদেন প্রজাদিক বলেছিলেন। কোনও টেবিলে বা টেবিলের সংমিশ্রণে একটি "স্ট্যাটিক ফিল্টার" হিসাবে দেখুন of উদাহরণস্বরূপ: একটি ভিউ টেবিলগুলি একত্রিত করতে পারে Orderএবং Customerতাই আপনি Orderগ্রাহকের নাম এবং গ্রাহকের নম্বর (টেবিলের সংমিশ্রণ) সহ নতুন কলামগুলি সহ সারিগুলির একটি নতুন "টেবিল" পান । অথবা আপনি এমন একটি ভিউ তৈরি করতে পারেন যা কেবলমাত্র অ-প্রক্রিয়াজাত আদেশগুলি নির্বাচন করেOrder টেবিল (স্ট্যাটিক ফিল্টার) ।

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


12

সাধারণত দর্শনগুলি প্যারামিটারাইজড হয় না। তবে আপনি সর্বদা কিছু পরামিতি ইনজেক্ট করতে পারেন। উদাহরণস্বরূপ সেশন প্রসঙ্গ ব্যবহার :

CREATE VIEW my_view
AS
SELECT *
FROM tab
WHERE num = SESSION_CONTEXT(N'my_num');

আবাহন:

EXEC sp_set_session_context 'my_num', 1; 
SELECT * FROM my_view;

এবং অন্য:

EXEC sp_set_session_context 'my_num', 2; 
SELECT * FROM my_view;

ডিবিফিডাল ডেমো

একই ওরাকল এর জন্য প্রযোজ্য (প্রসঙ্গ ফাংশনের জন্য অবশ্যই সিনট্যাক্স আলাদা)।


2
আমি মনে করি এটি বেশ সহজ। কীভাবে প্যারামিটারগুলি ওয়েব অ্যাপ্লিকেশনগুলিতে যেমন জাভাতে পাস করা যেতে পারে।
8:54

1
সহজ এবং ক্রিয়ামূলক! অন্য কথায় ... নিখুঁত! ধন্যবাদ!
রিকার্ডো বাসিলিচি

আমি ক্লান্ত. যেখানে যোগ করা হচ্ছে COOL = SESSION_CONTEXT (N'Ket '); ত্রুটির ফলস্বরূপ 'SESSION_CONTEXT' কোনও স্বীকৃত অন্তর্নির্মিত ফাংশনটির নাম নয়।
ব্যবহারকারী 123456

@ ইউজার 123456 আপনাকে এসকিউএল সার্ভার 2016 এবং তার বেশি বা
অ্যাজুরে

9

কেন আপনার দৃষ্টিভঙ্গির পরামিতি দরকার? আপনি কেবল WHEREক্লজ ব্যবহার করতে পারেন ।

create view v_emp as select * from emp ;

এবং আপনার প্রশ্নের কাজটি করা উচিত:

select * from v_emp where emp_id=&eno;

11
কিছু ক্ষেত্রে বড় পারফরম্যান্সের উন্নতি হবে, যখন এটি দেখার জন্য WHEREপরিবর্তে টেবিলের জন্য একটি WHERE
ডগ_ইভিজন

ডগ যা বলেছে তা কিছুটা সত্য হলেও, আধুনিক ডাটাবেসগুলি স্মৃতিচারণার সাথে একটি দৃষ্টিভঙ্গি 'প্রসারিত' এবং কার্যকরভাবে একই ফলাফলের সাথে শেষ করার মতো একটি দুর্দান্ত কাজ করতে পারে যেন আপনি নিজেই পুরো ক্যোয়ারী নিজেই করেছিলেন। সুতরাং ধরে নিবেন না এটি অকার্যকর হবে কারণ ডেটাবেস আপনাকে বিস্মিত করতে পারে - উত্পন্ন উত্পন্ন ক্যোয়ারী পরিকল্পনাটি দেখুন। একটি উল্লেখযোগ্য ব্যতিক্রম হ'ল যদি ভিউটিতে একটি গ্রুপের মাধ্যমে গ্রুপ থাকে যা আউটপুটকে প্রভাবিত করে - এমন ক্ষেত্রে আপনি 'বাহ্যিক' থেকে WHERE করতে পারেন না।
সাইমন_উইভার

8

সঞ্চিত প্রক্রিয়া বা ফাংশন ছাড়াই এটি করার একটি হ্যাকি উপায় হ'ল আপনার ডাটাবেজে একটি আইকন, প্যারাম 1, প্যারাম 2 ইত্যাদির সাথে একটি সেটিংস টেবিল তৈরি করা হবে that টেবিলটিতে আইড = 1, প্যারাম 1 = 0, প্যারাম 2 সহ একটি সারি প্রবেশ করান = 0, ইত্যাদি। তারপরে আপনি পছন্দসই প্রভাব তৈরি করতে আপনার ভিউতে সেই টেবিলটিতে একটি যোগ যোগ করতে পারেন এবং ভিউ চালানোর আগে সেটিংস টেবিলটি আপডেট করতে পারেন। আপনার যদি একাধিক ব্যবহারকারী থাকে তবে সেটিংস টেবিলটি আপডেট করা এবং একই সাথে ভিউ চালানো জিনিসগুলি ভুল হতে পারে, তবে অন্যথায় এটি ঠিক কাজ করা উচিত। কিছুটা এইরকম:

CREATE VIEW v_emp 
AS 
SELECT      * 
FROM        emp E
INNER JOIN  settings S
ON          S.Id = 1 AND E.emp_id = S.Param1

দেখার অনুরোধের জন্য এটি ব্যবহার করা ভয়ানক হবে। তবে এই জাতীয় লুকানো প্যারামিটার ব্যবহার করার জন্য এটি একটি কনফিগারেশন / পর্যায় / পরিবেশ হিসাবে সত্যই ব্যবহারযোগ্য। আমার জন্য এটি একটি প্লাস।
টিপাকটোপা

6

কোন। যদি আপনাকে অবশ্যই এমন কোনও ব্যবহারকারী সংজ্ঞায়িত ফাংশন ব্যবহার করতে হবে যেখানে আপনি পরামিতিগুলি পাস করতে পারেন।


5

না, কোনও ভিউ কোনও টেবিল থেকে নির্বাচন করতে আলাদাভাবে জিজ্ঞাসা করা হয় না।

আপনি যা চান তা করতে, এক বা একাধিক পরামিতি সহ একটি সারণী-মূল্যবান ব্যবহারকারী-সংজ্ঞায়িত ফাংশন ব্যবহার করুন


5

একটি ভিউ পূর্বনির্ধারিত 'নির্বাচন' বিবৃতি ছাড়া আর কিছুই নয়। সুতরাং একমাত্র আসল উত্তরটি হবে: না, আপনি পারবেন না।

আমি মনে করি আপনি যা করতে চান তা হ'ল একটি সঞ্চিত প্রক্রিয়া তৈরি করা, যেখানে নীতিমালায় আপনি প্যারামিটারগুলি গ্রহণ এবং ডেটা নির্বাচন করে যা চান তা করতে কোনও বৈধ এসকিউএল ব্যবহার করতে পারেন।

মনে হয় সম্ভবত আপনার দৃষ্টিভঙ্গিটি বেছে নেওয়ার সময় আপনাকে কেবলমাত্র একটি ক্লজ যুক্ত করতে হবে তবে আপনি নিশ্চিত হয়ে ওঠার জন্য যথেষ্ট বিশদ সরবরাহ করেন নি।


5

আমরা ইনপুট পরামিতি সহ একটি সঞ্চিত প্রক্রিয়া লিখতে পারি এবং তারপরে দৃশ্য থেকে ফলাফল সেট করতে সেই সঞ্চিত পদ্ধতিটি ব্যবহার করতে পারি। নীচে উদাহরণ দেখুন।

সঞ্চিত পদ্ধতিটি

CREATE PROCEDURE [dbo].[sp_Report_LoginSuccess] -- [sp_Report_LoginSuccess] '01/01/2010','01/30/2010'
@fromDate datetime,
@toDate datetime,
@RoleName varchar(50),
@Success int
as
If @RoleName != 'All'
Begin
   If @Success!=2
   Begin
   --fetch based on true or false
  Select * from vw_Report_LoginSuccess
  where logindatetime between  dbo.DateFloor(@fromDate) and dbo.DateSieling(@toDate)
  And RTrim(Upper(RoleName)) = RTrim(Upper(@RoleName)) and Success=@Success
   End
   Else
   Begin
    -- fetch all
  Select * from vw_Report_LoginSuccess
  where logindatetime between  dbo.DateFloor(@fromDate) and dbo.DateSieling(@toDate)
  And RTrim(Upper(RoleName)) = RTrim(Upper(@RoleName))
   End

End
Else
Begin
   If @Success!=2
   Begin
  Select * from vw_Report_LoginSuccess
  where logindatetime between  dbo.DateFloor(@fromDate) and dbo.DateSieling(@toDate)
  and Success=@Success
 End
 Else
 Begin
  Select * from vw_Report_LoginSuccess
  where logindatetime between  dbo.DateFloor(@fromDate) and dbo.DateSieling(@toDate)
 End

End

এবং যে ফলাফল থেকে আমরা ফলাফল সেট পেতে পারি তা হ'ল

CREATE VIEW [dbo].[vw_Report_LoginSuccess]
AS
SELECT     '3' AS UserDetailID, dbo.tblLoginStatusDetail.Success, CONVERT(varchar, dbo.tblLoginStatusDetail.LoginDateTime, 101) AS LoginDateTime,
                      CONVERT(varchar, dbo.tblLoginStatusDetail.LogoutDateTime, 101) AS LogoutDateTime, dbo.tblLoginStatusDetail.TokenID,
                      dbo.tblUserDetail.SubscriberID, dbo.aspnet_Roles.RoleId, dbo.aspnet_Roles.RoleName
FROM         dbo.tblLoginStatusDetail INNER JOIN
                      dbo.tblUserDetail ON dbo.tblLoginStatusDetail.UserDetailID = dbo.tblUserDetail.UserDetailID INNER JOIN
                      dbo.aspnet_UsersInRoles ON dbo.tblUserDetail.UserID = dbo.aspnet_UsersInRoles.UserId INNER JOIN
                      dbo.aspnet_Roles ON dbo.aspnet_UsersInRoles.RoleId = dbo.aspnet_Roles.RoleId
WHERE     (dbo.tblLoginStatusDetail.Success = 0)
UNION all
SELECT     dbo.tblLoginStatusDetail.UserDetailID, dbo.tblLoginStatusDetail.Success, CONVERT(varchar, dbo.tblLoginStatusDetail.LoginDateTime, 101)
                      AS LoginDateTime, CONVERT(varchar, dbo.tblLoginStatusDetail.LogoutDateTime, 101) AS LogoutDateTime, dbo.tblLoginStatusDetail.TokenID,
                      dbo.tblUserDetail.SubscriberID, dbo.aspnet_Roles.RoleId, dbo.aspnet_Roles.RoleName
FROM         dbo.tblLoginStatusDetail INNER JOIN
                      dbo.tblUserDetail ON dbo.tblLoginStatusDetail.UserDetailID = dbo.tblUserDetail.UserDetailID INNER JOIN
                      dbo.aspnet_UsersInRoles ON dbo.tblUserDetail.UserID = dbo.aspnet_UsersInRoles.UserId INNER JOIN
                      dbo.aspnet_Roles ON dbo.aspnet_UsersInRoles.RoleId = dbo.aspnet_Roles.RoleId
WHERE     (dbo.tblLoginStatusDetail.Success = 1) AND (dbo.tblUserDetail.SubscriberID LIKE N'P%')  

5

আমি জানি ভিউ সিলেক্ট কমান্ডের মতো কিছু হতে পারে। আপনি এই নির্বাচনের সাথে পরামিতিগুলি যুক্ত করতে পারেন উদাহরণস্বরূপ যেখানে বিবৃতি এখানে:

 WHERE  (exam_id = @var)

4

না, একটি দৃশ্য স্থির। আপনি যা করতে পারেন (এসকিউএল সার্ভারের সংস্করণের উপর নির্ভর করে) তা হল সূচককে দেখানো।

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


4

আপনি যদি কোনও ফাংশন ব্যবহার করতে না চান তবে আপনি এই জাতীয় কিছু ব্যবহার করতে পারেন

-- VIEW
CREATE VIEW [dbo].[vwPharmacyProducts]
AS
SELECT     PharmacyId, ProductId
FROM         dbo.Stock
WHERE     (TotalQty > 0)

-- Use of view inside a stored procedure
CREATE PROCEDURE [dbo].[usp_GetProductByFilter]
(   @pPharmacyId int ) AS

IF @pPharmacyId = 0 BEGIN SET @pPharmacyId = NULL END

SELECT  P.[ProductId], P.[strDisplayAs] FROM [Product] P
WHERE (P.[bDeleted] = 0)
    AND (P.[ProductId] IN (Select vPP.ProductId From vwPharmacyProducts vPP
                           Where vPP.PharmacyId = @pPharmacyId)
                       OR @pPharmacyId IS NULL
        )

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


3

না আপনি দেখতে প্যারামিটারটি পদ্ধতিতে পাস করতে পারেন


2

এখানে এমন একটি বিকল্প যা আমি এখনও পর্যন্ত দেখিনি:

আপনি যে কলামটি দেখার জন্য সীমাবদ্ধ রাখতে চান তা কেবল যুক্ত করুন:

create view emp_v as (
select emp_name, emp_id from emp;
)

select emp_v.emp_name from emp_v
where emp_v.emp_id = (id to restrict by)

1

আপনি কেবল ভিউ চালানোর জন্য বাইপাস করতে পারেন, এসকিউএল ওয়াইন করবে এবং কান্নাকাটি করবে তবে কেবল এটি করুন এবং চালান! আপনি সংরক্ষণ করতে পারবেন না।

create or replace view v_emp(eno number) as select * from emp where (emp_id = @Parameter1);

1

আপনার দর্শনটি আপনার পরামিতিগুলি সহ কিছু বাহ্যিক সারণী উল্লেখ করতে পারে।

অন্যরা যেমন উল্লেখ করেছে, এসকিউএল সার্ভারে দেখাতে বাহ্যিক ইনপুট প্যারামিটার থাকতে পারে না। তবে, আপনি সহজেই সিটিই ব্যবহার করে আপনার ভিউতে পরিবর্তনশীল নকল করতে পারেন। আপনি এটি আপনার এসকিউএল সার্ভারের সংস্করণে পরীক্ষা-চালনা করতে পারেন।

CREATE VIEW vwImportant_Users AS
WITH params AS (
    SELECT 
    varType='%Admin%', 
    varMinStatus=1)
SELECT status, name 
    FROM sys.sysusers, params
    WHERE status > varMinStatus OR name LIKE varType

SELECT * FROM vwImportant_Users

ফলন উত্পাদন:

status  name
12      dbo
0       db_accessadmin
0       db_securityadmin
0       db_ddladmin

এছাড়াও মাধ্যমে JOIN

WITH params AS ( SELECT varType='%Admin%', varMinStatus=1)
SELECT status, name 
    FROM sys.sysusers INNER JOIN params ON 1=1
    WHERE status > varMinStatus OR name LIKE varType

এছাড়াও মাধ্যমে CROSS APPLY

WITH params AS ( SELECT varType='%Admin%', varMinStatus=1)
SELECT status, name 
    FROM sys.sysusers CROSS APPLY params
    WHERE status > varMinStatus OR name LIKE varType

1
এটি হওয়া উচিত (পিএল / এসকিউএল এবং টি এসকিউএল বিভিন্ন উপায়ে একই রকম) তবে এটির জন্য আরও একাধিক উপায় রয়েছে :) চেষ্টা করে দেখুন।
ওলেগ মেল্নিকভ

0

আমার একটি ধারণা আছে যা আমি এখনও চেষ্টা করি নি। আপনি করতে পারেন:

CREATE VIEW updated_customers AS
SELECT * FROM customer as aa
LEFT JOIN customer_rec as bb
ON aa.id = bb.customer_id
WHERE aa.updated_at between (SELECT start_date FROM config WHERE active = 1) 
and (SELECT end_date FROM config WHERE active = 1)

আপনার পরামিতিগুলি সংরক্ষণ করা হবে এবং কনফিগার টেবিলটিতে পরিবর্তিত হবে।


2
যদি আপনার কোনও প্রতিক্রিয়ার সত্যতা সম্পর্কে সন্দেহ থাকে তবে এটি অন্তত পর্যাপ্ত সমাধান কিনা তা যাচাই করার আগে এটি পোস্ট করবেন না । যেমন দাঁড়িয়েছে, এটি উত্তরের চেয়ে আরও বেশি প্রশ্ন is
chb

এই সমাধানটির একটি সমস্যা হ'ল যদি একাধিক সেশনে কোয়েরিটি চলমান থাকে তবে কনফিগার টেবিলের ভুল ডেটা ব্যবহার করা যেতে পারে
ব্যবহারকারীর 1010

0

আমি নিম্নলিখিত হিসাবে আমার প্রয়োজনের জন্য এই কাজ বুঝতে পেরেছি

set nocount on;

  declare @ToDate date = dateadd(month,datediff(month,0,getdate())-1,0)

declare @year varchar(4)  = year(@ToDate)
declare @month varchar(2) = month(@ToDate)

declare @sql nvarchar(max)
set @sql = N'
    create or alter view dbo.wTempLogs
    as
    select * from dbo.y2019
    where
        year(LogDate) = ''_year_''
        and 
        month(LogDate) = ''_month_''    '

select @sql = replace(replace(@sql,'_year_',@year),'_month_',@month)

execute sp_executesql @sql

declare @errmsg nvarchar(max)
    set @errMsg = @sql
    raiserror (@errMsg, 0,1) with nowait
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.