error , query not executing because illegal context - sybase

The below query poping this error
The name 'name' is illegal in this context. Only constants, constant expressions, or variables allowed here. Column names are illegal.
why?
INSERT INTO UPGRADEd
(SCRIPT_CODE,
APP_NAME,
FILE_NAME,
DATE_APPLIED,
ACT_TYPE,
STATUS,
CREDENTIALS)
VALUES
( 'scriptcode',
'-appname-',
'-filename-',
getdate(),
'PC',
(select
case when count(1) = 1 then 'FAIL' else 'OK' end from sysobjects
where name = ''),
(select hostname from sysprocesses where spid = ##spid)
)

You can't mix insert .. values with insert..select. You should put everything in select statement as below
INSERT INTO UPGRADEd
( SCRIPT_CODE, APP_NAME, FILE_NAME, DATE_APPLIED,
ACT_TYPE, STATUS, CREDENTIALS)
select 'scriptcode','-appname-','-filename-',getdate(),
'PC',
case
when count(1) = 1
then 'FAIL'
else 'OK' end,
(select hostname from sysprocesses where spid = ##spid)
from sysobjects
where name = ''

Related

Simple Case query fails logic - what am I missing?

Why would this "Fail", if foo is less than 40 it should be "OK"
SELECT foo = '30', case when 'foo' >= '40' then 'Fail' else 'OK' end as 'Test'
So my actual query is (where ArrivalDate is a datetime):
SELECT Distinct [Title]
,DATEDIFF(day, [ArrivalDate], GetDate()) AS 'DaysOldSinceArrival'
,case when 'DaysOldSinceArrival' >= '40' then 'Fail' else 'OK' end as 'Test'
I believe the 'DaysOldSinceArrival' output must be a string and this is why the compare is not working. Is this failing for the same reason, if so, how do I make the 'DaysOldSinceArrival' an actual INT?
Your query is not correct, I feel you are trying to do something like following.
DECLARE #FOO INT
SET #FOO =30
SELECT #foo , case when #foo >= 40
then 'Fail' else 'OK' end as 'Test'
Output
(No column name) Test
30 OK
Issues in your query. You are comparing string 'foo' with a string
value '40', which is not ture.
EDIT
After looking your update, it seems you want to do like following
SELECT *,
(case when DaysOldSinceArrival >= 40 then 'Fail' else 'OK' end) as 'Test'
FROM
(
SELECT Distinct [Title]
,DATEDIFF(day, [ArrivalDate], GetDate()) AS 'DaysOldSinceArrival'
FROM [YOUR_TABLE]
) T
Yes, you are comparing a string to an INT which is implictly converted to a string and thus desn't equal your other string. You could use a CTE which can be more clear than a derrived table for some.
;with cte as(
SELECT
Distinct [Title]
,DaysOldSinceArrival = DATEDIFF(day, [ArrivalDate], GetDate()))
select
*
,Test = case when DaysOldSinceArrival >= 40 then 'Fail' else 'OK' end
from cte

SQL Query produces duplicates with "Where IN" query

I have a large SQL statement which does a whole load of joins on my tables. I have converted some of my table relationships to many-to-many relationships so that it is more efficient. I have therefore decided to convert my SQL to do a WHERE IN statement (on location).
The following query is the one that currently returns the desired results:
ALTER PROCEDURE [dbo].[GetMemberListing]
#Locations nvarchar(max)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
select
Member.Id,
AspNetUsers.Salutation,
AspNetUsers.FirstName,
AspNetUsers.PhotoUrl,
AspNetUsers.LastName,
AspNetUsers.Birthday,
AspNetUsers.Gender,
Member.IDType,
Member.JoinDate,
CONCAT (AspNetUsers.FirstName, ' ', AspNetUsers.LastName) as FullName,
AspNetUsers.CountryCode,
AspNetUsers.Email,
Location.Name as LocationName,
AspNetUsers.HomePhone as HomePhone,
coalesce(Package.Name,'No Package') as PackageName,
PackageTerm = case when Package.PackageIsReoccuring = 1 then 'Recurring' when Package.PackageIsSession = 1 then 'Paid In Full' when membership.TotalPrice = 0 then 'Free' when Package.PackagePayInFull = 1 then 'Paid In Full' end,
PackageType.Name as PackageType,
MembershipId = case when membership.id IS NULL THEN '' ELSE 0 end,
coalesce(membershipstate.name, 'N/A') as MembershipState,
MembershipStartDate = case when membership.StartDate IS NULL THEN '' ELSE CONVERT(varchar(50),membership.StartDate) end,
MembershipEndDate = case when membership.EndDate IS NULL THEN '' ELSE CONVERT(varchar(50),membership.EndDate) end
from
(
select
member.id as memberid,
(
select top 1 id
from membership
where memberid = member.id
and membership.StartDate <= getdate()
order by membership.enddate desc
) as membershipid
from member
) as LatestMembership
left join membership
on latestmembership.membershipid = membership.id
join member
on latestmembership.memberid = member.id
join AspNetusers
on member.AspNetUserId = AspNetUsers.Id
join Location
on member.HomeLocationId = Location.Id
left join Package
on membership.packageid = package.Id
left join PackageType
on package.packagetypeid = packagetype.Id
left join MembershipState
on membership.membershipstateid = membershipstate.Id
Order By aspNetusers.LastName desc
END
Below is what i have tried to do; however, it is duplicating the otherwise correct results based on the number of values in the WHERE IN join.
This on member.HomeLocationId = Location.Id
becomes on member.HomeLocationId IN (SELECT Value FROM fn_Split(#Locations, ','))
As seen below:
ALTER PROCEDURE [dbo].[GetMemberListing]
#Locations nvarchar(max)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
select
Member.Id,
AspNetUsers.Salutation,
AspNetUsers.FirstName,
AspNetUsers.PhotoUrl,
AspNetUsers.LastName,
AspNetUsers.Birthday,
AspNetUsers.Gender,
Member.IDType,
Member.JoinDate,
CONCAT (AspNetUsers.FirstName, ' ', AspNetUsers.LastName) as FullName,
AspNetUsers.CountryCode,
AspNetUsers.Email,
Location.Name as LocationName,
AspNetUsers.HomePhone as HomePhone,
coalesce(Package.Name,'No Package') as PackageName,
PackageTerm = case when Package.PackageIsReoccuring = 1 then 'Recurring' when Package.PackageIsSession = 1 then 'Paid In Full' when membership.TotalPrice = 0 then 'Free' when Package.PackagePayInFull = 1 then 'Paid In Full' end,
PackageType.Name as PackageType,
MembershipId = case when membership.id IS NULL THEN '' ELSE 0 end,
coalesce(membershipstate.name, 'N/A') as MembershipState,
MembershipStartDate = case when membership.StartDate IS NULL THEN '' ELSE CONVERT(varchar(50),membership.StartDate) end,
MembershipEndDate = case when membership.EndDate IS NULL THEN '' ELSE CONVERT(varchar(50),membership.EndDate) end
from
(
select member.id as memberid,
(
select top 1 id
from membership
where memberid = member.id
and membership.StartDate <= getdate()
order by membership.enddate desc
) as membershipid
from member
) as LatestMembership
left join membership
on latestmembership.membershipid = membership.id
join member
on latestmembership.memberid = member.id
join AspNetusers
on member.AspNetUserId = AspNetUsers.Id
join Location
on member.HomeLocationId IN (SELECT Value FROM fn_Split(#Locations, ','))
left join Package
on membership.packageid = package.Id
left join PackageType
on package.packagetypeid = packagetype.Id
left join MembershipState
on membership.membershipstateid = membershipstate.Id
Order By aspNetusers.LastName desc
END
Change to using your split function in the where clause. Don't use that function in the join.
In addition you don't really have a valid join condition on the locations table go back to this
on member.HomeLocationId = Location.Id
And later
Where member.HomeLocationId IN (SELECT Value FROM fn_Split(#Locations, ','))

How to write SQL query inside else statement in SQL Server

I want to find if query does not return any results, then print 'no records found' else execute the query.
Here is my query,
select case when exists (
SELECT CAST(dm.[ID] AS VARCHAR(100)) as ID, case when dm.[Que_Type] = 0 then 'Valid' else 'Invalid' end [Type],
dm.[Name_List], t.[Name], dm.[FromDate], dm.[ToDate] FROM tblDays dm(nolock)
inner join (select pr.ID, pr.name from tblProduct pr(nolock)) as t
on dm.TradeID = t.ID where 1=1 and dm.ToDate between GETDATE() and DATEADD(dd, 15, GETDATE()))
then 'ok'
else 'no records'
end
In this query, I want to execute the query instead of printing 'ok'. How can I do that?
You could use an if statement along with exists
Since the conditional check is just to see if any records are returned, there is no need to select all those columns, so we just select 1. If records are found, the if tests true, and we'll run the sql statement. If no records are found, we'll drop to the else block and print 'no records'.
This may work for you:
IF(
exists(
select 1
FROM tblDays dm(nolock)
inner join (select pr.ID, pr.name from tblProduct pr(nolock)) as t
on dm.TradeID = t.ID
where 1=1
and dm.ToDate between GETDATE() and DATEADD(dd, 15, GETDATE())
)
)
BEGIN
SELECT CAST(dm.[ID] AS VARCHAR(100)) as ID
, case when dm.[Que_Type] = 0 then 'Valid' else 'Invalid' end [Type]
, dm.[Name_List]
, t.[Name]
, dm.[FromDate]
, dm.[ToDate]
FROM tblDays dm(nolock)
inner join (select pr.ID, pr.name from tblProduct pr(nolock)) as t
on dm.TradeID = t.ID
where 1=1
and dm.ToDate between GETDATE() and DATEADD(dd, 15, GETDATE())
END
ELSE
BEGIN
print 'no records'
END
You could use ##ROWCOUNT:
According to BOL:
Returns the number of rows affected by the last statement.
SELECT
CAST(dm.[ID] AS VARCHAR(100)) AS ID,
CASE WHEN dm.[Que_Type] = 0 THEN 'Valid' ELSE 'Invalid' END AS [Type],
dm.[Name_List],
t.[Name],
dm.[FromDate],
dm.[ToDate]
FROM tblDays dm(NOLOCK)
INNER JOIN (
SELECT
pr.ID,
pr.name
FROM tblProduct pr(NOLOCK)
) AS t
ON dm.TradeID = t.ID
WHERE
1 = 1
AND dm.ToDate BETWEEN GETDATE() AND DATEADD(dd, 15, GETDATE())
IF ##ROWCOUNT = 0
PRINT 'No records found.'

Migrate Sql Server Stored Procedure to Oracle PL/SQL

The below stored procedure works for SQL Server (before I made some oracle specific changes).
Now this stored procedure must work for Oracle too.
The Oracle Sql Developer which I use complains at the line after the "OPEN CURSOR_ FOR"
Somehow Oracle does not like that I 'group' both select statements and the union and do on this whole result an order by...
What do I wrong? I only know a bit about oracle stored procedures...
create or replace
PROCEDURE GetWorkflowStatusForMatrix(
p_ApplicationId IN varchar2,
CURSOR_ OUT sys_refcursor
)
AS
BEGIN
OPEN CURSOR_ FOR
(
select ApplicationId || ModuleId || UNIT_ID as StatusKey, UNIT_ID, ApplicationId, ModuleId, Owner, "Level", Action, "Comment", LastModifiedUser, LastModifiedDate
from WorkflowStatus where ApplicationId = p_ApplicationId
union
select distinct e.ApplicationId + WorkflowId + UnitId as StatusKey, UnitId, e.ApplicationId, WorkflowId, w.Owner, 'Level1', 'Working', EventType, UserId, EventDateTime as LastModifiedDate
from EventLog e
join WorkflowStatus w on w.ApplicationId = e.ApplicationId and w.ModuleId = e.WorkflowId and w.UNIT_ID = e.UnitId
where e.ApplicationId = p_ApplicationId and w.Owner <> '' and w.Action = 'Created'
)
order by LastModifiedDate DESC;
END;
You need to read up on how to Define Cursors in Oracle - this will help you out..
http://www.techonthenet.com/oracle/cursors/declare.php
create or replace
PROCEDURE GetWorkflowStatusForMatrix(
p_ApplicationId IN varchar2,
CURSOR_ OUT sys_refcursor
)
AS
BEGIN
OPEN CURSOR_ FOR
select ApplicationId || ModuleId || UNIT_ID as StatusKey, UNIT_ID, ApplicationId, ModuleId, Owner, "Level", Action, "Comment", LastModifiedUser, LastModifiedDate
from WorkflowStatus where ApplicationId = p_ApplicationId
union
select distinct e.ApplicationId + WorkflowId + UnitId as StatusKey, UnitId, e.ApplicationId, WorkflowId, w.Owner, 'Level1', 'Working', EventType, UserId, EventDateTime as LastModifiedDate
from EventLog e
join WorkflowStatus w on w.ApplicationId = e.ApplicationId and w.ModuleId = e.WorkflowId and w.UNIT_ID = e.UnitId
where e.ApplicationId = p_ApplicationId and w.Owner <> '' and w.Action = 'Created'
order by LastModifiedDate DESC;
END;

T-SQL ERROR - Subquery returned more than 1 value

I am getting the following error in SQL Server:
Msg 512, Level 16, State 1, Line 18 Subquery returned more than 1
value. This is not permitted when the subquery follows =, !=, <, <= , > >, >= or when the subquery is used as an expression.
My code is as follows:
DECLARE
#personNumber varchar(20),
#itemNumber varchar(20)
SET #personNumber = 'null'
SET #itemNumber = 'null'
SELECT
OU.UserID
,OU.Name
,IGWQ.itemNumber
,IG.itemName
,IGWQ.QuantityOnHand
FROM dbo.Table1 IGWQ
INNER JOIN Table2 OU ON IGWQ.UserId = OU.UserId
INNER JOIN Table3 IG ON IGWQ.itemNumber = IG.itemNumber
WHERE IGWQ.userid IN (CASE WHEN #personNumber = 'null'
THEN ( SELECT DISTINCT
UserID
FROM Table2 WITH(NOLOCK)
WHERE [Role] = '01')
ELSE #personNumber
END)
AND IGWQ.itemNumber IN (CASE WHEN #itemNumber = 'null'
THEN ( SELECT DISTINCT
itemNumber
FROM dbo.Table1 WITH(NOLOCK))
ELSE #itemNumber
END)
Can anyone suggest a solution to this problem? I thought using 'IN' would have fixed the issue.
use this to fix the rest:
WHERE ((#personNumber <> 'null' AND #personNumber = IGWQ.userid)
OR (#personNumber = 'null' AND IGWQ.userid IN ( SELECT UserID
FROM Table2 WITH(NOLOCK)
WHERE [Role] = '01')
))
You don't need the DISTINCT as the IN statement only handles distinct values.
WHERE (IGWQ.userid = #personNumber OR
#personNumber = 'NULL' and
EXISTS (SELECT *
FROM Table2 t WITH (NOLOCK)
WHERE t.[Role] = '01' AND t.UserID = IGWQ.userid)
)
AND (IGWQ.itemNumber = #itemNumber OR
#itemNumber = 'NULL' and
EXISTS (SELECT *
FROM dbo.Table1 t WITH (NOLOCK)
WHERE t.itemNumber = IGWQ.itemNumber)
)
Notes:
CASE returns a scalar, it cannot return a subquery (i.e. set).
WITH (NOLOCK) is deprecated. change the connection isolation to READ UNCOMMITTED or SNAPSHOT instead.

Resources