هل يمكننا تمرير معلمة إلى طريقة عرض في Microsoft SQL Server؟
حاولت create view
بالطريقة التالية ، لكنها لا تعمل:
create or replace view v_emp(eno number) as select * from emp where emp_id=&eno;
كما ذكرت بالفعل لا يمكنك ذلك.
يتمثل الحل المحتمل في تنفيذ وظيفة مخزنة ، مثل:
CREATE FUNCTION v_emp (@pintEno INT)
RETURNS TABLE
AS
RETURN
SELECT * FROM emp WHERE [email protected];
يتيح لك ذلك استخدامه كطريقة عرض عادية ، مع:
SELECT * FROM v_emp(10)
هناك طريقتان لتحقيق ما تريد للأسف لا يمكن القيام به باستخدام طريقة عرض.
يمكنك إما إنشاء دالة معرّفة من قِبل المستخدم في الجدول والتي تأخذ المعلمة التي تريدها وتُرجع نتيجة استعلام
أو يمكنك فعل الشيء نفسه تمامًا ولكن يمكنك إنشاء إجراء مخزن بدلاً من دالة معرفة من قبل المستخدم.
فمثلا
فإن الإجراء المخزن تبدو
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]
)
لا لا يمكنك ، كما قال ملادين براجيتش. فكر في طريقة العرض كـ "عامل تصفية ثابت" على جدول أو مجموعة من الجداول. على سبيل المثال: قد تجمع طريقة العرض بين الجداول Order
و Customer
بحيث تحصل على "جدول" جديد من الصفوف من Order
مع أعمدة جديدة تحتوي على اسم العميل ورقم العميل (مجموعة من الجداول). أو يمكنك إنشاء طريقة عرض تحدد الطلبات غير المجهزة فقط من الجدول Order
(عامل التصفية الثابت).
بعد ذلك ، يمكنك تحديد طريقة العرض التي تريدها من أي جدول "عادي" آخر - يجب إجراء جميع عمليات التصفية "غير الثابتة" خارج العرض (مثل "الحصول على جميع الطلبات للعملاء الذين يطلق عليهم Miller" أو "الحصول على الطلبات غير المجهزة" التي جاءت في 24 ديسمبر ").
تتمثل الطريقة المخترقة للقيام بذلك دون إجراءات أو وظائف مخزنة في إنشاء جدول إعدادات في قاعدة البيانات الخاصة بك ، مع أعمدة معرف ، 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
لا يتم تحديد طرق العرض عادةً. ولكن يمكنك دائما حقن بعض المعلمات. على سبيل المثال باستخدام سياق الجلسة :
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;
الأمر نفسه ينطبق على Oracle (بناء الجملة بالطبع لوظيفة السياق مختلف).
لماذا تحتاج المعلمة في الرأي؟ يمكنك فقط استخدام جملة WHERE
.
create view v_emp as select * from emp ;
واستفسارك يجب القيام بهذه المهمة:
select * from v_emp where emp_id=&eno;
لا. إذا كان يجب عليك بعد ذلك استخدام دالة معرفة من قبل المستخدم يمكنك تمرير المعلمات إليها.
يمكننا كتابة إجراء مخزن مع معلمات الإدخال ثم استخدام هذا الإجراء المخزن للحصول على مجموعة نتائج من العرض. انظر المثال أدناه.
الإجراء المخزن هو
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%')
كما أعرف طريقة العرض يمكن أن يكون شيء مثل اختيار القيادة. يمكنك أيضًا إضافة معلمات إلى هذا التحديد على سبيل المثال في مكان عبارات مثل:
WHERE (exam_id = @var)
طريقة العرض ليست أكثر من عبارة "SELECT" المحددة مسبقًا. إذن الجواب الحقيقي الوحيد هو: لا ، لا يمكنك ذلك.
أعتقد أن ما تريد فعله حقًا هو إنشاء إجراء مخزن ، حيث يمكنك من حيث المبدأ استخدام أي SQL صالح للقيام بكل ما تريد ، بما في ذلك قبول المعلمات وتحديد البيانات.
يبدو أنك على الأرجح تحتاج فقط إلى إضافة جملة مكان عندما تختار من وجهة نظرك ، لكنك لم تقدم تفاصيل كافية بالتأكيد.
لا ، منظر ثابت. شيء واحد يمكنك القيام به (اعتمادًا على إصدار خادم SQl) هو فهرسة طريقة عرض.
في المثال الخاص بك (الاستعلام عن جدول واحد فقط) ، لن يكون للعرض المفهرس أي فائدة من مجرد الاستعلام عن الجدول بفهرس ، ولكن إذا كنت تقوم بالكثير من الصلات في الجداول بشروط الربط ، فإن طريقة العرض المفهرسة يمكنها تحسين الأداء بشكل كبير.
لا ، يتم الاستعلام عن طريقة عرض بطريقة مختلفة عن تحديد من جدول.
للقيام بما تريد ، استخدم دالة معرفة من قبل المستخدم بقيمة الجدول مع معلمة أو أكثر
إذا كنت لا ترغب في استخدام وظيفة ، يمكنك استخدام شيء مثل هذا
-- 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
)
آمل أن يساعد
لا يمكنك تمرير المعلمة إلى الإجراء في العرض
إليك خيار لم أره حتى الآن:
فقط أضف العمود الذي تريد تقييده على العرض:
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)
يمكنك تجاوز مجرد تشغيل العرض ، سوف SQL النبيذ والبكاء ولكن فقط القيام بذلك وتشغيله! لا يمكنك الحفظ.
create or replace view v_emp(eno number) as select * from emp where (emp_id = @Parameter1);
وجهة نظرك يمكن أن تشير إلى بعض الجداول الخارجية التي تحتوي على المعلمات الخاصة بك.
كما ذكر آخرون ، لا يمكن أن تحتوي طريقة العرض في 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
لدي فكرة أنني لم أحاول حتى الآن. يمكنك ان تفعل:
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)
سيتم حفظ المعلمات الخاصة بك وتغييرها في جدول التكوين.