RDL to SQL, Must declare the scalar variable - sql

I am trying to take a query I found in a RDL file and run it in SQL. I have no idea what I'm doing. I tried multiple solutions I found through searching the web to no avail. The errors I am getting are: "Must declare the scalar variable" for "#locale", "AuthListID", and "UserSIDs". Any suggestions on where to look or how I can fix this? I am very much a SQL n00b. Thank you in advance for any insight.
declare #lcid as int set #lcid = dbo.fn_LShortNameToLCID(CAST (#locale AS varchar(50))
declare #AuthListLocalID as int = case when IsNumeric(#AuthListID)=1 then cast(#AuthListID as int) else (select CI_ID from fn_rbac_AuthListInfo(#lcid,#UserSIDs) where CI_UniqueID=#AuthListID) end
declare #ci table(CI_ID int primary key, CI_UniqueID nvarchar(256), Title nvarchar(512), ArticleID nvarchar(64), BulletinID nvarchar(64), Vendor0 nvarchar(256))
insert #ci
select ui.CI_ID, ui.CI_UniqueID, ui.Title, ui.ArticleID, ui.BulletinID, ven.CategoryInstanceName
from fn_rbac_BundledConfigurationItems(#UserSIDs) bci
join fn_rbac_UpdateInfo(#lcid, #UserSIDs) ui on ui.CI_ID=bci.BundledCI_ID
left join fn_rbac_CICategoryInfo_All(#lcid, #UserSIDs) ven on ven.CI_ID=ui.CI_ID and ven.CategoryTypeName='Company'
where bci.CI_ID=#AuthListLocalID

It seems to me it should look something like this. Hopefully, you have access to all the functions being called, or you might have more digging to do.
DECLARE
#lcid int
, #AuthListLocalID int
, #locale varchar(50)
, #AuthListID int
, #UserSIDs int;
DECLARE #ci TABLE(CI_ID int primary key
, CI_UniqueID nvarchar(256)
, Title nvarchar(512)
, ArticleID nvarchar(64)
, BulletinID nvarchar(64)
, Vendor0 nvarchar(256));
SET #lcid = dbo.fn_LShortNameToLCID(#locale)
SET #AuthListLocalID = CASE
WHEN IsNumeric(#AuthListID)=1
THEN #AuthListID
ELSE (SELECT
CI_ID
FROM fn_rbac_AuthListInfo(#lcid,#UserSIDs)
WHERE CI_UniqueID=#AuthListID)
END
INSERT INTO #ci
VALUES (SELECT
ui.CI_ID
, ui.CI_UniqueID
, ui.Title
, ui.ArticleID
, ui.BulletinID
, ven.CategoryInstanceName
FROM fn_rbac_BundledConfigurationItems(#UserSIDs) bci
INNER JOIN fn_rbac_UpdateInfo(#lcid, #UserSIDs) ui
ON ui.CI_ID=bci.BundledCI_ID
LEFT OUTER JOIN fn_rbac_CICategoryInfo_All(#lcid, #UserSIDs) ven
ON ven.CI_ID=ui.CI_ID
AND ven.CategoryTypeName='Company'
WHERE bci.CI_ID=#AuthListLocalID)

Related

SQl Server Performance

I have database with more than 30 tables and more than 270k records in one table (the most important table) and create view get data from this table and other tables,
When I run the code below on my machine it takes less than 4 sec to get data from the view.
select * from view
My problem is that,
When I run the same script of database on another machine and run the same query from the view it takes a very long time.
Code for view
SELECT
dbo.UserSite.UserId,
dbo.UserSite.Name,
dbo.Site.RootPageURL,
dbo.PDFDocument.DocumentId,
dbo.RunDocumentVerificationResult.Status,
dbo.UserSite.UserSiteId,
dbo.Systemcode.Value,
dbo.RunDocumentVerificationResult.PageNumber,
dbo.RunDocumentVerificationResult.TestNameID,
dbo.RunDocumentVerificationResult.VerificationResultID,
dbo.TaskRun.VerificationEndDate,
dbo.TaskRun.RunId,
dbo.RunDocument.IsTagged,
dbo.RunDocument.IsProtected,
dbo.RunDocument.IsCorrupted
FROM
dbo.UserSite
INNER JOIN dbo.Site ON dbo.UserSite.SiteId = dbo.Site.SiteId
INNER JOIN dbo.TaskUserSites ON dbo.UserSite.UserSiteId = dbo.TaskUserSites.UserSiteId
INNER JOIN dbo.Task ON dbo.TaskUserSites.TaskId = dbo.Task.TaskId
INNER JOIN dbo.TaskRun ON dbo.Task.TaskId = dbo.TaskRun.TaskId
INNER JOIN dbo.RunDocument ON dbo.TaskRun.RunId = dbo.RunDocument.RunId
INNER JOIN dbo.PDFDocument ON dbo.PDFDocument.DocumentId = dbo.RunDocument.DocumentId
INNER JOIN dbo.RunDocumentVerificationResult ON dbo.RunDocument.RunDocumentId = dbo.RunDocumentVerificationResult.RunDocumentID
INNER JOIN dbo.Systemcode ON dbo.RunDocumentVerificationResult.Status = dbo.Systemcode.ID
EstimatedTime
Procdure Code is
ALTER proc [dbo].[status]
as
begin
begin transaction
declare #usersiteid bigint
declare #runid bigint
declare #TestedFiles int
declare #TaggedFiles int
declare #UnTaggedFiles int
declare #PassedFiles int
declare #FaildFiles int
declare #Name varchar(500)
declare #VerificationEndDate datetime
declare #RootPageURL varchar (1024)
declare #status table ( Name varchar(1000) , Urlrootpage varchar(2000) ,Testedfile int , TaggedFiles int , Untaggedfile int ,passedfiles int , faildfiles int,VerificationEndDate datetime,rootpageurl varchar(1024) )
declare #domain table (name varchar(1000) , urlrootpage varchar (2000) )
if (1=2)
begin
select 'n' Name ,'r' Urlrootpage ,1 Testedfile ,1 TaggedFiles ,0 Untaggedfile ,0 passedfiles ,0 faildfiles,GETDATE() VerificationEndDate ,'r' rootpageurl where 1=2
end
create table #status ( Name varchar(1000) , Urlrootpage varchar(2000) ,Testedfile int , TaggedFiles int , Untaggedfile int ,passedfiles int , faildfiles int,VerificationEndDate datetime,rootpageurl varchar(1024) )
set #usersiteid = (select min (UserSiteId) from vw)
set #runid = (select max (runid) from vw where usersiteid = #usersiteid)
while #usersiteid is not null
begin
set #TestedFiles = (select (count ( distinct documentid )) from vw where UserSiteId=#usersiteid and runid=#runid )
set #TaggedFiles = (select (count ( distinct documentid )) from vw where istagged=1 and UserSiteId=#usersiteid and runid=#runid)
set #UnTaggedFiles =(select (count ( distinct documentid )) from vw where istagged=0 and UserSiteId=#usersiteid and runid=#runid)
set #PassedFiles =(select (count ( distinct documentid )) from vw where Status<>1 and DocumentId not in (select DocumentId from vw where status =1) and UserSiteId=#usersiteid and runid=#runid)
set #FaildFiles = ( select (count ( distinct documentid )) from vw where Status=1 and UserSiteId=#usersiteid and runid=#runid)
set #Name = (select distinct name from vw where UserSiteId=#usersiteid)
set #rootPageUrl = (select distinct RootPageURL from vw where UserSiteId=#usersiteid)
set #VerificationEndDate = (select max(distinct VerificationEndDate) from vw where UserSiteId=#usersiteid and RunId=#runid)
insert into #status ( Name, Urlrootpage , Testedfile , TaggedFiles , Untaggedfile ,passedfiles , faildfiles ,VerificationEndDate ) values
(#Name,#RootPageURL,#TestedFiles,#TaggedFiles ,#UnTaggedFiles,#PassedFiles,#FaildFiles,#VerificationEndDate)
set #usersiteid = (select min (UserSiteId) from vw where UserSiteId > #usersiteid)
set #runid = (select max (runid) from vw where usersiteid = #usersiteid)
end
insert into #domain select UserSite.Name , Site.RootPageURL from UserSite inner join Site on UserSite.SiteId=Site.SiteId where UserSiteId not in (select UserSiteId from vw)
insert into #status select name,urlrootpage,0,0,0,0,0,null,0 from #domain
select Name,Urlrootpage,Testedfile,TaggedFiles,Untaggedfile, passedfiles,faildfiles from #status
end
If (##Error <> 0) -- Check if any error
Begin
rollback transaction
End
else
commit transaction
return
I would do a little test to find out if it is actually, as suggested, the network bandwidth that causes your query to be slow, or, better said, to look like it's slow. Append a limit-statement to your query and run it, like LIMIT 10. So while the whole query will execute, only the 10 first rows will be sent, and if the network is your bottleneck, it should now be very fast. If it is still that slow, your machine's sql server probably has very little memory to use, so it can't fit the whole result in, and your local sql server is probably configured to use more memory, so it executes faster. In this case, giving your sql server more memory should fix the problem. This should be no problem at all, since, as already mentioned in the comments, your database is actually very small, so the currently used memory will be very small too.
If your network connection turns out to be the bottleneck, you need to decide if, and why, you need all the results to be sent at once. I can't really help you on that one, since I don't know what the application is supposed to do with the data. But probably you should either do some aggegration in the database, or only send a small part of the data over the network.

SQL Server : print out cursor values

I want to be able to print out or output the values from a cursor for my stored procedure's. I'm having a hard time trying to figure out how to do this. I need to output my values onto a sheet like a report about which customers have paid and which haven't. A comparison would be great.
Here are my stored procedures for the customers who haven't paid:
CREATE PROC [dbo].[AdminReport1]
AS
BEGIN
SELECT
booking.bookingID, booking.totalCost,
booking.bookingDate, booking.paymentConfirmation,
customers.customersID,
customers.firstname, customers.surname,
customers.contactNum
FROM
booking
INNER JOIN
customers ON booking.customerID = customers.customersID
WHERE
paymentConfirmation = 'False'
ORDER BY
bookingDate ASC
END
GO
Here are my stored procedures for the customers who HAVE paid:
CREATE PROC [dbo].[AdminReport2]
AS
BEGIN
SELECT
booking.bookingID, booking.totalCost,
booking.bookingDate, booking.paymentConfirmation,
customers.customersID,
customers.firstname, customers.surname,
customers.contactNum
FROM
booking
INNER JOIN
customers ON booking.customerID = customers.customersID
WHERE
paymentConfirmation = 'TRUE'
ORDER BY
bookingDate ASC
So I need a cursor to print out my values. If anyone could help it would be much appreciated. An example with how to do this in code would be appreciated.
While I'm not convinced this is the most efficient way to do it (it would be better for SQL Server to feed the data to something designed to make display data; SSRS or even to Excel), here is what I would do as a start:
--Create somewhere to put the proc data and fill it. This will give us something tangible to query against.
CREATE TABLE #NotPaid
(
bookingID INT ,
totalCost DECIMAL(7, 2) ,
bookingDate DATE ,
paymentConfirmation VARCHAR(50) ,
customersID INT ,
firstname VARCHAR(50) ,
surname VARCHAR(50) ,
contactNum VARCHAR(50)
)
CREATE TABLE #HasPaid
(
bookingID INT ,
totalCost DECIMAL(7, 2) ,
bookingDate DATE ,
paymentConfirmation VARCHAR(50) ,
customersID INT ,
firstname VARCHAR(50) ,
surname VARCHAR(50) ,
contactNum VARCHAR(50)
)
INSERT #NotPaid
EXEC AdminReport1
INSERT #HasPaid
EXEC AdminReport2
--Variables for use in our cursor. I'm only loading one table up as a demonstration.
DECLARE #bookingID INT ,
#totalCost DECIMAL(7, 2) ,
#bookingDate DATE ,
#paymentConfirmation VARCHAR(50) ,
#customersID INT ,
#firstname VARCHAR(50) ,
#surname VARCHAR(50) ,
#contactNum VARCHAR(50)
DECLARE #Library CURSOR
SET
#Library = CURSOR FOR
SELECT bookingID ,
totalCost ,
bookingDate ,
paymentConfirmation ,
customersID ,
firstname,
surname ,
contactNum FROM #HasPaid
--Run the cursor and print out the variables as we loop again. Any formatting will need to be done in here. Again, I'm not sure this is the best way to achieve what you are trying to achieve.
OPEN #Library
FETCH NEXT FROM #getProductID INTO #bookingID, #totalCost, #bookingDate,
#paymentConfirmation, #customersID, #firstname, #surname, #contactNum
PRINT 'I''m a header line'
WHILE ##FETCH_STATUS = 0
BEGIN
PRINT #firstname + ' Hasnt paid! His booking date is ' + STR(#bookingDate)
+ '. This is the middle part'
FETCH NEXT FROM #Library INTO #bookingID, #totalCost, #bookingDate,
#paymentConfirmation, #customersID, #firstname, #surname, #contactNum
END
PRINT 'I''m at the bottom'
CLOSE #Library
DEALLOCATE #Library
GO
This should give you a fairly good starting place.
In terms of general efficiency, it would be better to just have the one proc and you pass in the information you want out, so, pass in the fact you just want the Paids, or just want the NotPaids, or everyone. And just to be a bore about it, SQL isn't really the place to be doing this type of formatting. There are much better tools out there for this!
I would suggest staying away from cursors unless there is a specific valid reason for using them. You could simplify this slightly by having a view which has the columns you are looking for
CREATE VIEW [dbo].[AdminReport]
AS
BEGIN
SELECT
b.bookingID,
b.totalCost,
b.bookingDate,
b.paymentConfirmation,
c.customersID,
customers.firstname,
c.surname,
c.contactNum,
paymentConfirmation
FROM
booking b
INNER JOIN customers c
ON b.customerID= c.customersID
--Where
--paymentConfirmation = 'False'
ORDER BY
bookingDate ASC
END
GO
And then you can just select the records paid records as
Select * from AdminReport where paymentConfirmation = 'TRUE'
and the unpaid ones as
Select * from AdminReport where paymentConfirmation = 'FALSE'

Scheduled Job in Sql Server

I have created job in sql i want the procedure should execute at particular time on everyday.
I know it is not so difficult but my SQL is in sharing Environment so how can fix the schedule..
I have created sample procedure my procedure will be similar to this....
ALTER PROCEDURE [dbo].[INSERTMULTIPLE]
AS
BEGIN
DECLARE #ID INT, #RAVINDER VARCHAR(100), #MONTY VARCHAR(100),#DINESH
VARCHAR(100),#ANKIT VARCHAR(100)
SET NOCOUNT ON;
CREATE TABLE #TEMPTABLE
(
ID INT PRIMARY KEY IDENTITY(1,1),
RAVINDER VARCHAR(100),
MONTY VARCHAR(100),
DINESH VARCHAR(100),
ANKIT VARCHAR(100)
)
BEGIN
INSERT INTO #TEMPTABLE(RAVINDER,MONTY,DINESH,ANKIT) SELECT
R.NAME,M.NAME,D.NAME,A.NAME FROM RAVINDER R
INNER JOIN MONTY M ON R.ID=M.RID
INNER JOIN DINESH D ON M.ID=D.MID
INNER JOIN ANKIT A ON D.ID=A.DID
END
DECLARE #pK INT
DECLARE #maxPK int
set #pK = 1
SELECT #maxPK = COUNT(*) FROM #TEMPTABLE
WHILE (#pK<=#maxPK )
BEGIN
select #ID = ID from #TEMPTABLE where ID=#pK
SELECT #RAVINDER = RAVINDER FROM #TEMPTABLE WHERE ID=#pK
SELECT #MONTY = MONTY FROM #TEMPTABLE WHERE ID=#pK
SELECT #DINESH = DINESH FROM #TEMPTABLE WHERE ID=#pK
SELECT #ANKIT = ANKIT FROM #TEMPTABLE WHERE ID=#pK
if(#pK<=#maxPK)
BEGIN
INSERT INTO INSERTALL(RAVINDER,MONTY,DINESH,ANKIT
)VALUES(#RAVINDER,#MONTY,#DINESH,#ANKIT)
END
SET #pK=#pK+1
END
END
Ask your sharing provider. How comes you even consider us knowing how a provider - not even named by you - internall handles that? Ouch.
If that does not work, forget about it. Schedule OUTSIDE - i.e. from your website or another app - and call the SP once per day at the desired time. Pretty much the better way anyway in terms of knowing what goes on. There are a number of web cron services out there that can call a URL at a specified time.

Delete and insert on same procedure

In my SQL stored procedure, I need to delete and insert on same query. My syntax is below. But my syntax fails to store data. Why does it fail? How do I solve this problem? My syntax is
CREATE PROCEDURE spInsertCollectionInspectionHours
#StartDate DATETIME ,
#EndDate DATETIME ,
#ID BIGINT ,
#VesselName VARCHAR(80) ,
#VoyageNo VARCHAR(15) ,
#PortCode VARCHAR(20) ,
#Terminal VARCHAR(70) ,
#InspectionDate DATETIME ,
#InvoiceHours INT ,
#ManifestType INT ,
#Remarks NVARCHAR(200)
AS
BEGIN
BEGIN
DELETE FROM dbo.InspectionHours
WHERE InspectionDate BETWEEN #StartDate AND #EndDate
END
BEGIN
SELECT #ID = ISNULL(MAX(ID), 0) + 1
FROM [InspectionHours]
INSERT INTO [InspectionHours]
( [ID] ,
[VesselName] ,
[VoyageNo] ,
[PortCode] ,
[Terminal] ,
[InspectionDate] ,
[InvoiceHours] ,
[ManifestType] ,
[Remarks]
)
VALUES ( #ID ,
#VesselName ,
#VoyageNo ,
#PortCode ,
#Terminal ,
#InspectionDate ,
#InvoiceHours ,
#ManifestType ,
#Remarks
)
END
END
If have any questions please ask. Thanks in advance.
check your id field identity property is true or not if it's true or yes then no need to give id in insert statement
Your syntax is fine. This should not produce and error.
Your insert statement is also fine. If it is not throwing an error then something else is going on. Are you sure you are passing parameters? Are you sure you are looking in the correct server/db/table and using the correct query to check? Are you positive it's not throwing an error?

Usage of Array in Sql Possible?

I am trying to write a stored proicedure that gets all the townID's from Region_TownPage table. Then i should get the City, Stateinitials of all the townID's.
Alter PROCEDURE [dbo].[GetTownDetailsforRegionID]
#RegionID int
AS
BEGIN
Declare #townID int
set #townID = (Select townID from Region_TownPage where regionID =#RegionID)
SET NOCOUNT ON;
Select City, StateInitials,TownID from TownPage where TownID =#townID
END
I do not know how to use an array here in sql. If someone could help me doing this, i really appreciate that.
Thanks in advance!!
I don't think you need an array - you just need to join the tables?
Select r.RegionId,
t.TownId,
t.City,
t.StateInitials
From Region_TownPage r
Join TownPage t on r.TownId = t.TownId
Where r.RegionId = #RegionId
you would declare a table variable instead of an int. so it would be something like
DECLARE #tab table(townID int)
INSERT INTO #tab
SELECT townID from Region_TownPage WHERE regionID = #RegionID
Select * From TownPage WHERE TownID IN(SELECT townID FROM #tab)