it-swarm.asia

هل يمكننا تمرير المعلمات إلى طريقة عرض في SQL؟

هل يمكننا تمرير معلمة إلى طريقة عرض في Microsoft SQL Server؟

حاولت create view بالطريقة التالية ، لكنها لا تعمل:

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

كما ذكرت بالفعل لا يمكنك ذلك.

يتمثل الحل المحتمل في تنفيذ وظيفة مخزنة ، مثل:

CREATE FUNCTION v_emp (@pintEno INT)
RETURNS TABLE
AS
RETURN
   SELECT * FROM emp WHERE [email protected];

يتيح لك ذلك استخدامه كطريقة عرض عادية ، مع:

SELECT * FROM v_emp(10)
112
Alex Bagnolini

هناك طريقتان لتحقيق ما تريد للأسف لا يمكن القيام به باستخدام طريقة عرض.

يمكنك إما إنشاء دالة معرّفة من قِبل المستخدم في الجدول والتي تأخذ المعلمة التي تريدها وتُرجع نتيجة استعلام

أو يمكنك فعل الشيء نفسه تمامًا ولكن يمكنك إنشاء إجراء مخزن بدلاً من دالة معرفة من قبل المستخدم.

فمثلا

فإن الإجراء المخزن تبدو

CREATE PROCEDURE s_emp
(
    @enoNumber INT
) 
AS 
SELECT
    * 
FROM
    emp 
WHERE 
    [email protected]

أو وظيفة المستخدم المعرفة ستبدو

CREATE FUNCTION u_emp
(   
    @enoNumber INT
)
RETURNS TABLE 
AS
RETURN 
(
    SELECT    
        * 
    FROM    
        emp 
    WHERE     
        [email protected]
)
31
Gavin

لا لا يمكنك ، كما قال ملادين براجيتش. فكر في طريقة العرض كـ "عامل تصفية ثابت" على جدول أو مجموعة من الجداول. على سبيل المثال: قد تجمع طريقة العرض بين الجداول Order و Customer بحيث تحصل على "جدول" جديد من الصفوف من Order مع أعمدة جديدة تحتوي على اسم العميل ورقم العميل (مجموعة من الجداول). أو يمكنك إنشاء طريقة عرض تحدد الطلبات غير المجهزة فقط من الجدول Order (عامل التصفية الثابت).

بعد ذلك ، يمكنك تحديد طريقة العرض التي تريدها من أي جدول "عادي" آخر - يجب إجراء جميع عمليات التصفية "غير الثابتة" خارج العرض (مثل "الحصول على جميع الطلبات للعملاء الذين يطلق عليهم Miller" أو "الحصول على الطلبات غير المجهزة" التي جاءت في 24 ديسمبر ").

13
Thorsten Dittmar

تتمثل الطريقة المخترقة للقيام بذلك دون إجراءات أو وظائف مخزنة في إنشاء جدول إعدادات في قاعدة البيانات الخاصة بك ، مع أعمدة معرف ، Param1 ، Param2 ، إلخ. إدراج صف في هذا الجدول يحتوي على القيم معرف = 1 ، Param1 = 0 ، Param2 = 0 ، إلخ. ثم يمكنك إضافة صلة إلى هذا الجدول في طريقة العرض الخاصة بك لإنشاء التأثير المطلوب ، وتحديث جدول الإعدادات قبل تشغيل العرض. إذا كان لديك عدة مستخدمين يقومون بتحديث جدول الإعدادات وتشغيل العرض بشكل متزامن ، فقد تسوء الأمور ، ولكن يجب أن يعمل بشكل جيد. شيء مثل:

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

لا يتم تحديد طرق العرض عادةً. ولكن يمكنك دائما حقن بعض المعلمات. على سبيل المثال باستخدام سياق الجلسة :

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;

DBFiddle Demo

الأمر نفسه ينطبق على Oracle (بناء الجملة بالطبع لوظيفة السياق مختلف).

8
Lukasz Szozda

لماذا تحتاج المعلمة في الرأي؟ يمكنك فقط استخدام جملة WHERE.

create view v_emp as select * from emp ;

واستفسارك يجب القيام بهذه المهمة:

select * from v_emp where emp_id=&eno;
7
Mahesh

لا. إذا كان يجب عليك بعد ذلك استخدام دالة معرفة من قبل المستخدم يمكنك تمرير المعلمات إليها.

6
Mladen Prajdic

يمكننا كتابة إجراء مخزن مع معلمات الإدخال ثم استخدام هذا الإجراء المخزن للحصول على مجموعة نتائج من العرض. انظر المثال أدناه.

الإجراء المخزن هو

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 [email protected]
   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 [email protected]
 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
sunil

كما أعرف طريقة العرض يمكن أن يكون شيء مثل اختيار القيادة. يمكنك أيضًا إضافة معلمات إلى هذا التحديد على سبيل المثال في مكان عبارات مثل:

 WHERE  (exam_id = @var)
5
Reza Ameri

طريقة العرض ليست أكثر من عبارة "SELECT" المحددة مسبقًا. إذن الجواب الحقيقي الوحيد هو: لا ، لا يمكنك ذلك.

أعتقد أن ما تريد فعله حقًا هو إنشاء إجراء مخزن ، حيث يمكنك من حيث المبدأ استخدام أي SQL صالح للقيام بكل ما تريد ، بما في ذلك قبول المعلمات وتحديد البيانات.

يبدو أنك على الأرجح تحتاج فقط إلى إضافة جملة مكان عندما تختار من وجهة نظرك ، لكنك لم تقدم تفاصيل كافية بالتأكيد.

5
Kris

لا ، منظر ثابت. شيء واحد يمكنك القيام به (اعتمادًا على إصدار خادم SQl) هو فهرسة طريقة عرض.

في المثال الخاص بك (الاستعلام عن جدول واحد فقط) ، لن يكون للعرض المفهرس أي فائدة من مجرد الاستعلام عن الجدول بفهرس ، ولكن إذا كنت تقوم بالكثير من الصلات في الجداول بشروط الربط ، فإن طريقة العرض المفهرسة يمكنها تحسين الأداء بشكل كبير.

4
John

لا ، يتم الاستعلام عن طريقة عرض بطريقة مختلفة عن تحديد من جدول.

للقيام بما تريد ، استخدم دالة معرفة من قبل المستخدم بقيمة الجدول مع معلمة أو أكثر

4
MartW

إذا كنت لا ترغب في استخدام وظيفة ، يمكنك استخدام شيء مثل هذا

-- 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
Adnan Badar

لا يمكنك تمرير المعلمة إلى الإجراء في العرض

3
aicuxiao

إليك خيار لم أره حتى الآن:

فقط أضف العمود الذي تريد تقييده على العرض:

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)
2
FarajDaoud

يمكنك تجاوز مجرد تشغيل العرض ، سوف SQL النبيذ والبكاء ولكن فقط القيام بذلك وتشغيله! لا يمكنك الحفظ.

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

وجهة نظرك يمكن أن تشير إلى بعض الجداول الخارجية التي تحتوي على المعلمات الخاصة بك.

كما ذكر آخرون ، لا يمكن أن تحتوي طريقة العرض في SQL Server على معلمات الإدخال الخارجية. ومع ذلك ، يمكنك بسهولة مزيف متغير في طريقة العرض الخاصة بك باستخدام CTE. يمكنك اختبار تشغيله في إصدار SQL Server الخاص بك.

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
Oleg Melnikov

لدي فكرة أنني لم أحاول حتى الآن. يمكنك ان تفعل:

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)

سيتم حفظ المعلمات الخاصة بك وتغييرها في جدول التكوين.

0
Emman