How does this create view code work? - sql

Ok, so here is example code for view. Second part with select RT.RoleID[...] seems clear to me. That's the part that's going to be displayed when the query will be run to use the view. first part is unclear though.
First two lines are standard as i understand, then goes the whole with section. Could someone explain it to me? Never seen with "something" as (select) formula
CREATE VIEW [dbo].[sviw_System_MyPermissions_CurrentDomain]
AS
WITH MyDomainRoles AS (
SELECT RM.Domain, RM.RoleID
FROM stbl_System_RolesMembersDomains AS RM WITH (NOLOCK)
WHERE RM.Domain = (SELECT CurrentDomain FROM stbl_System_Users WITH (NOLOCK) WHERE Login = SUSER_SNAME())
AND RM.Login = SUSER_SNAME()
)
SELECT RT.RoleID, RT.TableName, DR.Domain, RT.GrantUpdate, RT.GrantInsert, RT.GrantDelete
FROM stbl_System_RolesTables AS RT WITH (NOLOCK)
JOIN MyDomainRoles AS DR ON RT.RoleID = DR.RoleID
GO

It is called Common Table Expresion and basically your view is the same as:
CREATE VIEW vSalesStaffQuickStats
AS
SELECT E.EmployeeID,
EmployeeOrders = OS.NumberOfOrders,
EmployeeLastOrderDate = OS.MostRecentOrderDate,
E.ManagerID,
ManagerOrders = OM.NumberOfOrders,
ManagerLastOrderDate = OM.MostRecentOrderDate
FROM HumanResources.Employee AS E
INNER JOIN (
SELECT SalesPersonID, COUNT(*) NumberOfOrders
, MAX(OrderDate) MostRecentOrderDate
FROM Sales.SalesOrderHeader
GROUP BY SalesPersonID
) AS OS
ON E.EmployeeID = OS.SalesPersonID
LEFT OUTER JOIN (
SELECT SalesPersonID, COUNT(*) NumberOfOrders
, MAX(OrderDate) MostRecentOrderDate
FROM Sales.SalesOrderHeader
GROUP BY SalesPersonID
) AS OM
ON E.ManagerID = OM.SalesPersonID
As you see you could easily exchange it with subquery. But in your case you need do it twice (with CTE you do it only once).
EDIT:
With new query after update:
CREATE VIEW [dbo].[sviw_System_MyPermissions_CurrentDomain]
AS
SELECT RT.RoleID, RT.TableName, DR.Domain, RT.GrantUpdate, RT.GrantInsert, RT.GrantDelete
FROM stbl_System_RolesTables AS RT WITH (NOLOCK)
JOIN (
SELECT RM.Domain, RM.RoleID
FROM stbl_System_RolesMembersDomains AS RM WITH (NOLOCK)
WHERE RM.Domain = (SELECT CurrentDomain FROM stbl_System_Users WITH (NOLOCK) WHERE Login = SUSER_SNAME())
AND RM.Login = SUSER_SNAME()
) AS DR ON RT.RoleID = DR.RoleID

The WITH keyword just refers to Common Table Expression ( read more here: https://learn.microsoft.com/en-us/sql/t-sql/queries/with-common-table-expression-transact-sql ) Basically everything within the WITH statement could be considered as externalized subquery which result set is then used in the main query.
i.e.:
WITH MyDomainRoles AS (
--- sub-query Start
SELECT RM.Domain, RM.RoleID
FROM stbl_System_RolesMembersDomains AS RM WITH (NOLOCK)
WHERE RM.Domain = (SELECT CurrentDomain FROM stbl_System_Users WITH (NOLOCK) WHERE Login = SUSER_SNAME())
AND RM.Login = SUSER_SNAME()
--- sub-query End
)
... and the result set from the sub-query above is held within the CTE named MyDomainRoles. Then you can refer to MyDomainRoles as to a table. Makes things simpler to read and cleaner to write.
Since this CTE is so simple, you could easily re-write it as follows but it just does not look as neat:
WITH MyDomainRoles AS (
)
SELECT RT.RoleID, RT.TableName, DR.Domain, RT.GrantUpdate, RT.GrantInsert, RT.GrantDelete
FROM stbl_System_RolesTables AS RT WITH (NOLOCK)
JOIN (
SELECT RM.Domain, RM.RoleID
FROM stbl_System_RolesMembersDomains AS RM WITH (NOLOCK)
WHERE RM.Domain = (SELECT CurrentDomain FROM stbl_System_Users WITH (NOLOCK) WHERE Login = SUSER_SNAME())
AND RM.Login = SUSER_SNAME()
) AS DR ON RT.RoleID = DR.RoleID

Related

Find all SELECT statements without a WHERE clause using a regex

I'm trying to scan my codebase to find all select queries without a where clause using regex. The results will be fed into an IDE or a grep file output, but must contain the full matching queries only.
My biggest challenge is getting the entire statement without the WHERE. The caveats are:
some selects don't have a where but also don't have a FROM
some selects target a database view (always starts with a vw) which don't need a where clause
Here's a sample list of all queries fetched from one file:
'
DECLARE #RowsAffected INT = 0;
INSERT INTO tblInvoice (InvID, OcID, InvTimeStamp)
SELECT DISTINCT OcInvID, OcID, GETDATE() AS InvTimeStamp
FROM tblOrderCost OC WITH(NOLOCK)
INNER JOIN tblVendor WITH(NOLOCK) ON InvVendorID = VendorID AND VendorType = 1 -- 1 for supplier.
INNER JOIN #tmpOpID tmp WITH(NOLOCK) ON tmp.OpID = OcOpID
WHERE id = ' . quote($order_id, NUMERIC);
$sql = ' SELECT rphrpid,rphwho,rphdate,rphnotes,opid
FROM tblReplacementPartHistory (nolock)
INNER JOIN tblReplacementPart (nolock)
ON rphrpid = rpid
INNER JOIN tblOrderProduct (nolock)
ON rpopid = opid
WHERE oporid =' . quote($order_id, NUMERIC)
. 'ORDER BY rphrpid';
select * from table where id = 1;
'
select count()
';
DECLARE #RowsAffected INT = 0;
INSERT INTO tblInvoice (InvID, OcID, InvTimeStamp)
SELECT DISTINCT OcInvID, OcID, GETDATE() AS InvTimeStamp
FROM tblOrderCost OC WITH(NOLOCK)
INNER JOIN tblVendor WITH(NOLOCK) ON InvVendorID = VendorID AND VendorType = 1
INNER JOIN #tmpOpID tmp WITH(NOLOCK) ON tmp.OpID = OcOpID';
$sql = ' SELECT rphrpid,rphwho,rphdate,rphnotes,opid
FROM tblReplacementPartHistory (nolock)
INNER JOIN tblReplacementPart (nolock)
ON rphrpid = rpid
INNER JOIN tblOrderProduct (nolock)
ON rpopid = opid
ORDER BY rphrpid';
SELECT rphrpid,rphwho,rphdate,rphnotes,opid
FROM vwOrder';
select * from tbl;
I tried several variations of regex patterns and the closest I got was finding matches with the WHERE line stripped out. I would like to have the entire match made only if the query does not have a WHERE clause. I tried the following
SELECT(.*)(\s)*FROM(\s|.)+?((?!.*where))(?=(';|";|;))
SELECT\s*(?!.*\s*where|vw(\w)*).*\s*(';|";|;)
SELECT[^;\n]*(?:\n(?![^\n;]*where)[^;\n]*)*\n[\n]*
The work can also be tested in the regex101 sandbox: https://regex101.com/r/jvbLOE/1
What I expect to see, given the sample data, is only three matches
1. SELECT DISTINCT OcInvID, OcID, GETDATE() AS InvTimeStamp
FROM tblOrderCost OC WITH(NOLOCK)
INNER JOIN tblVendor WITH(NOLOCK) ON InvVendorID = VendorID AND VendorType = 1
INNER JOIN #tmpOpID tmp WITH(NOLOCK) ON tmp.OpID = OcOpID';
2. SELECT rphrpid,rphwho,rphdate,rphnotes,opid
FROM tblReplacementPartHistory (nolock)
INNER JOIN tblReplacementPart (nolock)
ON rphrpid = rpid
INNER JOIN tblOrderProduct (nolock)
ON rpopid = opid
ORDER BY rphrpid';
3. select * from tbl;
You can use following regex to match select queries not having a where clause in it based on your example.
/(?!.*where)select.*?;/gis
Regex 101 example:
https://regex101.com/r/XaGXp6/1

The generated query by EF Core runs very slow in some conditions

We are using EF core in our application
In one of the Services, the EF core generates the below TSQL and runs. but it is prolonged!
exec sp_executesql N'SELECT [di].[Id] AS [Key], [di].[Code], [di].[DocumentTypeRef], [di].[IsActive], [di].[IsVisible], [di].[IsGlobal], [di].[IsPrintable], [di].[RecordPrefix], [di].[Owner_PersonRef], [owner].[FullName] AS [DocumentInfoOwnerFullName], [dil].[_Title] AS [ThisIsA_Title], [dil].[_Description] AS [_Description0], [docw].[WorkbenchRef], [t].[_Title] AS [_WorkbenchTitle], [t].[_Description] AS [_WorkbenchDescription], [docc].[CompanyRef], [cl].[_Title] AS [_CompanyTitle], [dt].[IsRecordable] AS [DocumentTypeIsRecordable], [dt].[ReviewCycle] AS [DocumentTypeReviewCycle], [dtl].[_Title] AS [_DocumentTypeTitle], [dtl].[_Description] AS [_DocumentTypeDescription], [t0].[Id] AS [DocumentVersionKey], [t0].[Creator_PersonRef] AS [DocumentVersionCreator_PersonRef], [t0].[EffectiveDate] AS [DocumentVersionEffectiveDate], [t0].[ExpireDate] AS [DocumentVersionExpireDate], [t0].[IsActive] AS [DocumentVersionIsActive], [t0].[PublishDate] AS [DocumentVersionPublishDate], [t0].[VersionNo] AS [DocumentVersionVersionNo], [t0].[ReviewDate] AS [DocumentVersionReviewDate], [t0].[ItemRowRef_DocVersionState], [t1].[FullName] AS [DocumentVersionCreatorFullName], [t2].[_Title] AS [_DocVersionStateTitle]
FROM [QMS].[DocumentInfo] AS [di]
INNER JOIN [QMS].[DocumentInfoLanguage] AS [dil] ON [di].[Id] = [dil].[DocumentInfoRef]
INNER JOIN [QMS].[DocumentCompany] AS [docc] ON [di].[Id] = [docc].[DocumentInfoRef]
INNER JOIN [HRM].[CompanyLanguage] AS [cl] ON [docc].[CompanyRef] = [cl].[CompanyRef]
INNER JOIN [QMS].[DocumentType] AS [dt] ON [di].[DocumentTypeRef] = [dt].[Id]
INNER JOIN [QMS].[DocumentTypeLanguage] AS [dtl] ON [dt].[Id] = [dtl].[DocumentTypeRef]
INNER JOIN [BAS].[PersonLanguage] AS [owner] ON [di].[Owner_PersonRef] = [owner].[PersonRef]
LEFT JOIN [QMS].[DocumentWorkbench] AS [docw] ON [di].[Id] = [docw].[DocumentInfoRef]
LEFT JOIN (
SELECT [x].*
FROM [QMS].[WorkbenchLanguage] AS [x]
WHERE [x].[LanguageRef] = #__languageRef_0
) AS [t] ON [docw].[WorkbenchRef] = [t].[WorkbenchRef]
LEFT JOIN (
SELECT [x0].*
FROM [QMS].[DocumentVersion] AS [x0]
WHERE ([x0].[ExpireDate] IS NULL OR ([x0].[ExpireDate] > GETDATE())) AND ([x0].[EffectiveDate] < GETDATE())
) AS [t0] ON [di].[Id] = [t0].[DocumentInfoRef]
LEFT JOIN (
SELECT [x1].*
FROM [BAS].[PersonLanguage] AS [x1]
WHERE [x1].[LanguageRef] = #__languageRef_1
) AS [t1] ON [t0].[Creator_PersonRef] = [t1].[PersonRef]
LEFT JOIN (
SELECT [x2].*
FROM [BAS].[ItemRowLanguage] AS [x2]
WHERE [x2].[LanguageRef] = #__languageRef_2
) AS [t2] ON [t0].[ItemRowRef_DocVersionState] = [t2].[ItemRowRef]
WHERE (((((([dil].[LanguageRef] = #__languageRef_3) AND ([cl].[LanguageRef] = #__languageRef_4)) AND ([dtl].[LanguageRef] = #__languageRef_5)) AND ([owner].[LanguageRef] = #__languageRef_6))
AND (CHARINDEX(N''we'', [dil].[_Title]) > 0))
AND [docc].[CompanyRef] IN (CAST(3 AS smallint))) AND ([di].[IsVisible] = 1)
ORDER BY (SELECT 1)
OFFSET #__p_8 ROWS FETCH NEXT #__p_9 ROWS ONLY',N'#__languageRef_0 int,#__languageRef_1 int,#__languageRef_2 int,#__languageRef_3 int,#__languageRef_4 int,#__languageRef_5 int,#__languageRef_6 int,#__p_8 int,#__p_9 int',#__languageRef_0=1,#__languageRef_1=1,#__languageRef_2=1,#__languageRef_3=1,#__languageRef_4=1,#__languageRef_5=1,#__languageRef_6=1,#__p_8=0,#__p_9=25
I got this query from SQL Profiler and tried to run it on SSMS
It ran again, but again it was slow!
I tried to find the problem. after a while I realized when I ignored some portion of the query, the query runs fast! for example when I deleted some of the JOINs, everything runs perfectly, or when I deleted the left hand of WHERE condition, again everything was OK! Even when I replaced the CHARINDEX with LIKE, again! the query ran fast.
I finally realized that the query is only running slowly if these combinations are placed together, which is very strange
It is possible that I am wrong. But no matter how hard I tried, I did not understand the reason for this behavior
Now can anyone help to understand this problem and find a solution for it?

SQL- basic but still finding it complicated

I am working on SQL query which should return the list of Managers and the staff who reports to them.
Unfortunately there is no separate table for Employee or Staff but a single 'resource' table called ahsresources.
The managers are identified with a relation called 'C0'.
Even after trying various Joins, I am unable to extract the list. The idea is that a manager will run the report to see his reportees, as well as those staff who report to his own reportees
Example -
Now, if lets say HDY is running the query, then its should return him the below result
Below is the query I have created, but for the matter of understanding the issue, you can use the above example.
select a.description as manager1,a.rel_value as MGID,a.resource_id as Reportee1_MGR2,r.name,a.date_to as date, r.date_to,a1.resource_id as MG3ID,r1.name as Rep3Name,
a2.resource_id as MG4ID,r2.name as Rep4Name
from ahsrelvalue a
LEFT OUTER JOIN ahsresources r
ON r.resource_id = a.resource_id and r.client = a.client and a.date_to='12/31/2099'
LEFT OUTER JOIN ahsrelvalue a1
ON a1.rel_Value = a.resource_id and a1.client = a.client and a1.date_to = '12/31/2099'
LEFT OUTER JOIN ahsrelvalue a2
ON a2.rel_Value = a1.resource_id and a2.client = a1.client and a2.date_to = '12/31/2099'
LEFT OUTER JOIN ahsresources r1
ON r1.resource_id = a1.resource_id and r1.client = a1.client and a1.date_to='12/31/2099'
LEFT OUTER JOIN ahsresources r2
ON r2.resource_id = a2.resource_id and r2.client = a2.client and a2.date_to='12/31/2099'
where a.rel_Value = '$?resid' and a.rel_attr_id='C0' and r.date_to = '12/31/2099' and r1.date_to ='12/31/2099'
and r.status !='C' and r1.status!='C' and r2.status!='C'
In SQL Server, you can use a recursive query to traverse this hierarchical dataset:
with cte as (
select t.* from mytable where managerID = 6
union all
select t.*
from cte c
inner join mytable t on t.managerID = c.staffID
)
select * from cte

SQL Query join issues

I am using SQL Server 2005.
I'm having some issues when executing this query.
My code is
ALTER PROCEDURE [dbo].[Get]
#ApplicantID int
AS
BEGIN
SELECT
isnull(M_EvalApplicationStatuses.EvalApplicationStatus,'') EvalApplicationStatus,
isnull(M_Users.CompletionMailSent,'') MailSent,
isnull(APP_Applications.FirstName,'') FirstName,
isnull(APP_Applications.LastName,'') LastName,
isnull(M_Users.UserName,'') UserName,
isnull(APP_Applications.DocTrackingGenComment,'') DocTrackingGenComment
FROM
APP_Applications
left outer join
M_Users
ON
APP_Applications.UserID = M_Users.UserID
left outer join
M_EvalApplicationStatuses
ON
APP_Applications.Status = M_EvalApplicationStatuses.EvalApplicationStatusID and M_EvalApplicationStatuses.Status = 1
WHERE
ApplicantID =#ApplicantID
END
This now works perfectly. But I want to get data from another table, so I just left join that table to this query. Here I have found the issue. My new table name is [APP_DocumentTracking] and the below query I used to retrieve data.
SELECT DISTINCT
isnull(APP_DocumentTracking.Date,'') Date,
isnull(APP_DocumentTracking.IntervTime,'') IntervTime,
isnull(APP_DocumentTracking.Telephoneinterview,'') Telephoneinterview
FROM [APP_DocumentTracking]
where APP_DocumentTracking.ApplicantID = #ApplicantID
These two queries are separately working fine... but I want to join these two queries and the result will be get in one table. How can I do this? plz help me
As per your comment in sarathkumar's answer the problem is Ambiguous column name 'ApplicantID'. Try the below for that problem. I have updated the where clause from your comment.
left outer join [APP_DocumentTracking] on [APP_DocumentTracking].ApplicantID=APP_Applications.ApplicantID
WHERE [APP_DocumentTracking].ApplicantID =#ApplicantID END
ALTER PROCEDURE [dbo].[Get]
#ApplicantID int
AS
BEGIN
SELECT
isnull(M_EvalApplicationStatuses.EvalApplicationStatus,'') EvalApplicationStatus,
isnull(M_Users.CompletionMailSent,'') MailSent,
isnull(APP_Applications.FirstName,'') FirstName,
isnull(APP_Applications.LastName,'') LastName,
isnull(M_Users.UserName,'') UserName,
isnull(APP_Applications.DocTrackingGenComment,'') DocTrackingGenComment
FROM APP_Applications
left outer join M_Users
ON APP_Applications.UserID = M_Users.UserID
left outer join
M_EvalApplicationStatuses
ON
APP_Applications.Status = M_EvalApplicationStatuses.EvalApplicationStatusID and M_EvalApplicationStatuses.Status = 1
left join
(
SELECT DISTINCT
isnull(APP_DocumentTracking.Date,'') Date,
isnull(APP_DocumentTracking.IntervTime,'') IntervTime,
isnull(APP_DocumentTracking.Telephoneinterview,'') Telephoneinterview
APP_DocumentTracking.ApplicantID
FROM [APP_DocumentTracking]
where APP_DocumentTracking.ApplicantID = #ApplicantID
) AliasSubquery
on 1=1
WHERE
ApplicantID =#ApplicantID
END
Just join as a subquery with first and second one .Please update the structure in SqlFiddle or here Itself.Then it will be easy to give u the answer...
Here is the code
ALTER PROCEDURE [dbo].[Get]
#ApplicantID int
AS
BEGIN
SELECT
isnull(M_EvalApplicationStatuses.EvalApplicationStatus,'') EvalApplicationStatus,
isnull(M_Users.CompletionMailSent,'') MailSent,
isnull(APP_Applications.FirstName,'') FirstName,
isnull(APP_Applications.LastName,'') LastName,
isnull(M_Users.UserName,'') UserName,
isnull(APP_Applications.DocTrackingGenComment,'') DocTrackingGenComment
,Trace.*
FROM
APP_Applications
left outer join
M_Users
ON
APP_Applications.UserID = M_Users.UserID
left outer join
M_EvalApplicationStatuses
ON
APP_Applications.Status = M_EvalApplicationStatuses.EvalApplicationStatusID and M_EvalApplicationStatuses.Status = 1
LEFT JOIN
(SELECT DISTINCT
isnull(APP_DocumentTracking.Date,'') Date,
isnull(APP_DocumentTracking.IntervTime,'') IntervTime,
isnull(APP_DocumentTracking.Telephoneinterview,'') Telephoneinterview
FROM [APP_DocumentTracking]
where APP_DocumentTracking.ApplicantID = #ApplicantID
) AS Trace
ON APP_Applications.ApplicantID = Trace.ApplicantID
WHERE APP_Applications.ApplicantID =#ApplicantID
END
Cheers.

Oracle - Way to rewrite this query to not use sub-selects?

I'm trying to create a materialized view in Oracle 11.1, which apparently does not support nested selects in a materialized view (Why this is, I haven't been able to figure out).. Is there a way to write this query to work as a materialized view? Thanks!
CREATE MATERIALIZED VIEW MV_Area90DayReport
NOLOGGING
CACHE
BUILD IMMEDIATE
REFRESH FAST ON COMMIT
AS
select
T.TASKID,
V.PROJECTID,
V.VERSIONID,
T.GOLDDATE,
P.BUSINESSLAUNCHDATE,
V.NAME as ProjectName,
T.NAME as TaskName,
T.COURSECODE,
DT.NAME as DeliveryMethod,
T.DELIVERABLELENGTHHOUR,
T.DELIVERABLELENGTHMINUTE,
V.PRIORITY,
(SELECT MIN(STARTDATE) FROM TPM_TRAININGPLAN WHERE PROJECTID=V.PROJECTID AND TRAININGPLANTYPE='prescribed') as TrainingDeliveryDate,
(SELECT wm_concat(WORKGROUPID) FROM TPM_PROJECTWORKGROUPS WHERE PROJECTID=V.PROJECTID GROUP BY PROJECTID) as Workgroups,
from TPM_TASK T
inner join TPM_PROJECTVERSION V ON (V.PROJECTID = T.PROJECTID AND V.VERSIONID = T.VERSIONID)
inner join TPM_PROJECT P ON (P.PROJECTID = T.PROJECTID)
inner join TPM_DOCUMENTTYPE DT ON (DT.DOCUMENTTYPEID = T.DOCUMENTTYPEID);
The error I get is:
>[Error] Script lines: 1-25 -------------------------
ORA-22818: subquery expressions not allowed here
Script line 20, statement line 20, column 115
I believe this is a limitation (that was raised as a bug sometime back), documented here on the Oracle site - http://download.oracle.com/docs/cd/B12037_01/server.101/b10736/basicmv.htm#sthref431
To resolve, you should use JOINS rather than subqueries.
Try the following query:
select
T.TASKID,
V.PROJECTID,
V.VERSIONID,
T.GOLDDATE,
P.BUSINESSLAUNCHDATE,
V.NAME as ProjectName,
T.NAME as TaskName,
T.COURSECODE,
DT.NAME as DeliveryMethod,
T.DELIVERABLELENGTHHOUR,
T.DELIVERABLELENGTHMINUTE,
V.PRIORITY,
TP.TrainingDeliveryDate,
WG.Workgroups,
from TPM_TASK T
inner join TPM_PROJECTVERSION V ON (V.PROJECTID = T.PROJECTID AND V.VERSIONID = T.VERSIONID)
inner join TPM_PROJECT P ON (P.PROJECTID = T.PROJECTID)
inner join TPM_DOCUMENTTYPE DT ON (DT.DOCUMENTTYPEID = T.DOCUMENTTYPEID)
left join (
SELECT PROJECTID, MIN(STARTDATE) as TrainingDeliveryDate
FROM TPM_TRAININGPLAN
WHERE TRAININGPLANTYPE='prescribed'
GROUP BY PROJECTID
) TP on TP.PROJECTID=V.PROJECTID
left join (
SELECT PROJECTID, wm_concat(WORKGROUPID) as Workgroups
FROM TPM_PROJECTWORKGROUPS
GROUP BY PROJECTID
) WG on WG.PROJECTID=V.PROJECTID