I have created a stored procedure that calculates from some table and retrieve a new dataset back:
" DECLARE #maxVal int " +
" Set #maxVal = (SELECT ID FROM TableCustomers " +
" WHERE Service_ID = #Service_ID) " +
" execute SP_CaculateData #maxVal ";
Now the TableCustomers also have a column called CustomerName and each CustmerName can have multiple Service_ID's.
How can I run my stored procedure multiple times, all depends on how many services each CustomerName has. Something like:
execute SP_CaculateData #maxVal
execute SP_CaculateData #maxVal
execute SP_CaculateData #maxVal
execute SP_CaculateData #maxVal
I have been reading something about cursors, but if anyone can give me a hand hear I would appreciate that.
One option is to use a while loop to iterate through the customers and service ids:
declare
#maxVal int
,#customerName varchar(200)
,#serviceID int
select #customerName = MIN(CustomerName)
from TableCustomers t
while(select COUNT(1)
from TableCustomers t
where t.CustomerName >= #customerName) > 0
begin
--here we are dealing w/ a specific customer
--loop through the serviceIDs
select #serviceID = MIN(Service_ID)
from TableCustomers t
where t.CustomerName = #customerName
while(select COUNT(1)
from TableCustomers t
where t.CustomerName = #customerName
and t.Service_ID >= #serviceID) > 0
begin
select #maxVal = MAX(Id)
from TableCustomers t
where t.Service_ID = #serviceID
execute SP_CalculateData #maxVal
select #serviceID = MIN(Service_ID)
from TableCustomers t
where t.CustomerName = #customerName
and t.Service_ID > #serviceID
end
select #customerName = MIN(CustomerName)
from TableCustomers t
where t.CustomerName > #customerName
end
I can't say whether or not this is a solution that will perform better than a cursor, but it should get the job done.
Related
I'm a little bit conffused.
Can anyone tell me why i get sintaxis error on the next script?
declare #schema1 NVARCHAR(100)
set #schema1 = 'ex.:DATABASENAME'
declare #query NVARCHAR(500)
set #query = 'INSERT UsersSessions (UserSessionId, IpAddress, ChannelId, IsEmployee, UserId, ClientFullName, UserAgent, StartDate, ExpirationDate, SessionDuration)
SELECT us.UserSessionId, us.IpAddress, us.ChannelId, CASE WHEN us.ChannelId = 2 THEN 1 ELSE 0 END AS IsEmployee, us.UserId, (u.Name + u.LastName) as ClientFullName, us.UserAgent, us.StartDate, us.ExpirationDate, (us.ExpirationDate-us.StartDate) AS SessionDuration
FROM ' + #schema1 + '.UsersSessions us INNER JOIN ' + #schema1 + '.Users u ON us.UserId = u.UserId WHERE us.UserSessionId NOT IN (SELECT UserSessionId FROM UsersSessions)'
EXEC(#query)
RESULT:
Msg 156, Level 15, State 1, Line 15
Incorrect syntax near the keyword 'Use'.
Completion time: 2021-11-16T11:10:32.6309920-03:00
If i remove the Insert block, i get the script running
declare #schema1 NVARCHAR(100)
set #schema1 = 'ex.:DATABASENAME'
declare #query NVARCHAR(500)
set #query = '
SELECT us.UserSessionId, us.IpAddress, us.ChannelId, CASE WHEN us.ChannelId = 2 THEN 1 ELSE 0 END AS IsEmployee, us.UserId, (u.Name + u.LastName) as ClientFullName, us.UserAgent, us.StartDate, us.ExpirationDate, (us.ExpirationDate-us.StartDate) AS SessionDuration
FROM ' + #schema1 + '.UsersSessions us INNER JOIN ' + #schema1 + '.Users u ON us.UserId = u.UserId WHERE us.UserSessionId NOT IN (SELECT UserSessionId FROM UsersSessions)'
EXEC(#query)
RESULT:
(1 row affected)
Completion time: 2021-11-16T11:11:07.6741062-03:00
I think some char is missing?
Thanks and regards!
Your query variable length is not sufficient, modify it as below. Also, schema name can accept only certain characters, colon is not allowed I guess.
declare #query NVARCHAR(max)
I have a Query string inside Employees Page that read URL Parameter
to get Companies employees from DataBase if parameter is ALL the page should display ALL Employees but if CompID Equal Specific ID it will Get only Employees for this Company to do that i am using two queries but i am sure that i can use only one query to get the same result
my Query String Parameter is :
String CompID = HttpUtility.UrlDecode(Request.QueryString["CompID"]);
The SQL Query to display ALL Employee is :
Query1 = "SELECT TbEmp.empID, TbEmp.fName, TbEmp.lName, TbEmp.email," +
" TbEmp.phoneNbr, TbEmp.compID, TbEmp.gender, " +
"TbEmp.address, TbComp.compName From TbEmp" +
" INNER JOIN TbComp on TbComp.compID = TbEmp.compID ORDER BY TbComp.compID"
The SQL Query to Display Employees for specific companie is :
Query2 = "SELECT TbEmp.empID, TbEmp.fName, TbEmp.lName, TbEmp.email," +
" TbEmp.phoneNbr, TbEmp.compID, TbEmp.gender, " +
"TbEmp.address, TbComp.compName From TbEmp" +
" INNER JOIN TbComp on TbComp.compID = TbEmp.compID WHERE TbEmp.compID = #CompID ORDER BY TbComp.compID DESC"
Can someone help me to merge those two queries in one query ?
The is a simple or-and case. Assuming your #CompID is numeric and you can send a zero to indicate the 'All' search...
INNER JOIN TbComp on TbComp.compID = TbEmp.compID
WHERE (#CompID = 0) or (#CompID <> 0 and TbEmp.compID = #CompID)
ORDER BY TbComp.compID DESC"
Although I would not suggest using queries to write your logic in asp.net (use stored procedures with parameters instead).
You can do this :
Solution 1 :
string Query1 = "SELECT TbEmp.empID, TbEmp.fName, TbEmp.lName, TbEmp.email," +
" TbEmp.phoneNbr, TbEmp.compID, TbEmp.gender, " +
"TbEmp.address, TbComp.compName From TbEmp" +
" INNER JOIN TbComp on TbComp.compID = TbEmp.compID " ;
String CompID = HttpUtility.UrlDecode(Request.QueryString["CompID"]);
if( CompID<>"")
{
Query1 += " WHERE TbEmp.compID = " + CompID //Beware : Chance of injection
}
Query1 +=" ORDER BY TbComp.compID";
Solution 2 : Assuming #CompID will be passed null if it is not there.
Query2 = "SELECT TbEmp.empID, TbEmp.fName, TbEmp.lName, TbEmp.email," +
" TbEmp.phoneNbr, TbEmp.compID, TbEmp.gender, " +
"TbEmp.address, TbComp.compName From TbEmp" +
" INNER JOIN TbComp on TbComp.compID = TbEmp.compID WHERE
TbEmp.compID = Isnull(#CompID, TbEmp.compID) ORDER BY TbComp.compID DESC"
I have a checkboxlist. The selected (checked) items are stored in List<string> selected.
For example, value selected is monday,tuesday,thursday out of 7 days
I am converting List<> to a comma-separated string, i.e.
string a= "monday,tuesday,thursday"
Now, I am passing this value to a stored procedure as a string. I want to fire query like:
Select *
from tblx
where days = 'Monday' or days = 'Tuesday' or days = 'Thursday'`
My question is: how to separate string in the stored procedure?
If you pass the comma separated (any separator) string to store procedure and use in query so must need to spit that string and then you will use it.
Below have example:
DECLARE #str VARCHAR(500) = 'monday,tuesday,thursday'
CREATE TABLE #Temp (tDay VARCHAR(100))
WHILE LEN(#str) > 0
BEGIN
DECLARE #TDay VARCHAR(100)
IF CHARINDEX(',',#str) > 0
SET #TDay = SUBSTRING(#str,0,CHARINDEX(',',#str))
ELSE
BEGIN
SET #TDay = #str
SET #str = ''
END
INSERT INTO #Temp VALUES (#TDay)
SET #str = REPLACE(#str,#TDay + ',' , '')
END
SELECT *
FROM tblx
WHERE days IN (SELECT tDay FROM #Temp)
Try this:
CREATE FUNCTION [dbo].[ufnSplit] (#string NVARCHAR(MAX))
RETURNS #parsedString TABLE (id NVARCHAR(MAX))
AS
BEGIN
DECLARE #separator NCHAR(1)
SET #separator=','
DECLARE #position int
SET #position = 1
SET #string = #string + #separator
WHILE charindex(#separator,#string,#position) <> 0
BEGIN
INSERT into #parsedString
SELECT substring(#string, #position, charindex(#separator,#string,#position) - #position)
SET #position = charindex(#separator,#string,#position) + 1
END
RETURN
END
Then use this function,
Select *
from tblx
where days IN (SELECT id FROM [dbo].[ufnSplit]('monday,tuesday,thursday'))
try this
CREATE FUNCTION Split
(
#delimited nvarchar(max),
#delimiter nvarchar(100)
) RETURNS #t TABLE
(
-- Id column can be commented out, not required for sql splitting string
id int identity(1,1), -- I use this column for numbering splitted parts
val nvarchar(max)
)
AS
BEGIN
declare #xml xml
set #xml = N'<root><r>' + replace(#delimited,#delimiter,'</r><r>') + '</r></root>'
insert into #t(val)
select
r.value('.','varchar(max)') as item
from #xml.nodes('//root/r') as records(r)
RETURN
END
GO
usage:
select * from tblx where days in (select val from dbo.split('monday,tuesday,thursday',','))
I think you want this
SELECT * FROM tblx where days in ('Monday','Tuesday','Thursday')
you can get it like this:
var a = "monday,tuesday,thursday";
var sql = string.Format("Select * from tblx where days IN ('{0}')", string.Join("','",a.Split(new[] {','})));
I face the same problem, and i try all the way but not get expected solution. Finally i did like follow. Try it hope it will work...
create Function [dbo].[Split]
(
#RowData NVARCHAR(MAX),
#SplitOn NVARCHAR(5)
)
RETURNS #RtnValue TABLE
(
Id INT IDENTITY(1,1),
Data NVARCHAR(100)
)
AS
BEGIN
DECLARE #Cnt INT
SET #Cnt = 1
WHILE (Charindex(#SplitOn,#RowData)>0)
BEGIN
INSERT INTO #RtnValue (data)
SELECT Data = ltrim(rtrim(Substring(#RowData,1,Charindex(#SplitOn,#RowData)-1)))
SET #RowData = Substring(#RowData,Charindex(#SplitOn,#RowData)+1,len(#RowData))
SET #Cnt = #Cnt + 1
END
INSERT INTO #RtnValue (data)
SELECT Data = ltrim(rtrim(#RowData))
RETURN
END
And in the store procedure put the code like that.
select #ActualTarget= count(*) from UpdateVisitDetails where CreatedBy IN (SELECT [DATA] FROM [dbo].[Split](#AllDATS,',' ))
I have same problem. I tried this.. and this was properly run
ALTER FUNCTION [dbo].[Split]
(
#List varchar(max),
#SplitOn nvarchar(5)
)
RETURNS #RtnValue table
(
Id int identity(1,1),
Value nvarchar(max)
)
AS
BEGIN
IF (len(#List) <=0)
Begin
Return
End
While (Charindex(#SplitOn,#List)>0)
Begin
Insert Into #RtnValue (value)
Select
Value = ltrim(rtrim(Substring(#List,1,Charindex(#SplitOn,#List)-1)))
Set #List = Substring(#List,Charindex(#SplitOn,#List)+len(#SplitOn),len(#List))
End
Insert Into #RtnValue (Value)
Select Value = ltrim(rtrim(#List))
Return
END
Run :
SELECT * FROM dbo.Split('Apple,Banana,Mango',',')
Output:
I am trying to get data from oracle database using asp.net but I am not getting any output in cursor while data is present in table:
I am using following stored procedure:
CREATE OR REPLACE PROCEDURE branch_details
( startIndex in int
,pageSize in int
,isSearch in int
,byName in int
,dataDetail in varchar2
, p_cursor out sys_refcursor)
AS
BEGIN
IF isSearch=1 THEN
IF byName=1 THEN
OPEN p_cursor FOR
SELECT *
FROM (SELECT ROW_NUMBER() OVER(ORDER BY branch_id)
AS MyRows
, branch_id, branch_name
, branch_location, bm_name, bm_contact
, bm_email, is_active, max_ua
, (SELECT COUNT(branch_id)
FROM branch_info
WHERE branch_name LIKE
'%'|| dataDetail||'%')
AS RowNumber
FROM branch_info
WHERE branch_name LIKE '%'|| dataDetail||'%')
WHERE MyRows BETWEEN startIndex
AND startIndex+pageSize-1;
ELSE
OPEN p_cursor FOR
SELECT *
FROM (SELECT ROW_NUMBER() OVER(ORDER BY branch_id)
AS MyRows
, branch_id, branch_name, branch_location
, bm_name, bm_contact, bm_email, is_active
, max_ua
, (SELECT COUNT(branch_id)
FROM branch_info
WHERE branch_id LIKE
'%'|| dataDetail||'%')
As RowNumber
FROM branch_info
WHERE branch_id LIKE '%'|| dataDetail||'%')
WHERE MyRows BETWEEN startIndex
AND startIndex+pageSize-1;
END IF;
ELSE
OPEN p_cursor FOR
SELECT *
FROM (SELECT ROW_NUMBER() OVER(ORDER BY branch_id)
AS MyRows
, branch_id, branch_name, branch_location
, bm_name, bm_contact, bm_email
, is_active, max_ua
, (SELECT COUNT(branch_id)
FROM branch_info) AS RowNumber
FROM branch_info)
WHERE MyRows BETWEEN startIndex
AND startIndex+pageSize-1;
END IF;
END;
And using following asp.net code:
List<Paramarray> param = new List<Paramarray>();
param.Add(new Paramarray("#dataDetail", data));
param.Add(new Paramarray("#byName", id?"0":"1"));
param.Add(new Paramarray("#isSearch", isSearch?"1":"0"));
param.Add(new Paramarray("#startIndex", startIndex==1?startIndex.ToString():Convert.ToString(((startIndex-1)*pageSize)+1)));
param.Add(new Paramarray("#pageSize", pageSize.ToString()));
_command.Connection = _connection;
_command.CommandType = CommandType.StoredProcedure;
_command.CommandText = "branch_details";
foreach (Paramarray _param in param)
{
_parameter = new OracleParameter(_param.name,_param.value);
_command.Parameters.Add(_parameter);
}
_command.Parameters.Add("#p_cursor", OracleDbType.RefCursor).Direction = ParameterDirection.Output;
if (_connection.State != ConnectionState.Open) _connection.Open();
_dataReader = _command.ExecuteReader();
dt.Load(_dataReader);
if (_connection.State == ConnectionState.Open) _connection.Close();
My same code for another procedure is working fine and giving me output.
Please help me if I am wrong in my procedure or somewhere else. I am not able to figure the problem.
I am going to wager that your procedure is wrong. Your asp.net code looks fine and without more information it seems to me that the cursor is just not returning any data.
Have you unit tested the procedure or even just the cursor queries?
I've run into a rather annoying problem which I cannot seem to get to the root of.
I've searched the internet for similar problems - and I've found a few unanswered in other forums - so I thought I'd give it a go here.
The following WebMethod of a webservice contacts a database, which works fine, and runs a stored procedure.
The problem is, that when I pass the parameters as single characters it tells me it cannot find either of the parameters and when I pass a full length "ean" parameter it tells me the following error message:
System.Data.OleDb.OleDbException: Error converting data type varchar to int.
at System.Data.OleDb.OleDbDataReader.ProcessResults(OleDbHResult hr)
at System.Data.OleDb.OleDbDataReader.NextResult()
at System.Data.OleDb.OleDbCommand.ExecuteReaderInternal(CommandBehavior behavior, String method)
at System.Data.OleDb.OleDbCommand.ExecuteReader(CommandBehavior behavior)
at System.Data.OleDb.OleDbCommand.ExecuteReader()
at Service.GetOthersRatings(Int32 personID, String ean)
And now here's the Webmethod:
[WebMethod(Description = "GetRatings")]
public string GetRatings(int personID, string ean)
{
string ratings = "";
OleDbConnection connection = new OleDbConnection(connectionString);
OleDbCommand command = new OleDbCommand("GetRatings", connection);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add("#personID",OleDbType.Integer,10).Value = personID;
command.Parameters.Add("#ean",OleDbType.VarChar,30).Value = ean;
try
{
connection.Open();
myReader = command.ExecuteReader();
if (myReader.HasRows)
{
while (myReader.Read())
{
ratings = myReader.GetString(0);
}
}
else
{
ratings = "Null";
}
}
catch (Exception e)
{
ratings = "Error - " + e.ToString();
}
finally
{
}
return ratings;
}
One thing that's worth mentioning is that if I remove the OUTPUT part of the SP, it runs fine down to and returns
ratings = "Null";
But seeing that I try to read a String from the reader, I don't see why it wouldn't work with a varchar output from the SP.
In the Database we have the corresponding Stored Procedure, which works fine if just executed in SQL Server Management Studio:
IF ( OBJECT_ID('GetRatings') IS NOT NULL )
DROP PROCEDURE GetRatings
GO
CREATE PROCEDURE GetRatings
#ratingschars varchar(36) = NULL OUTPUT,
#personID int,
#ean varchar(30)
AS
BEGIN TRAN
SET NOCOUNT ON;
BEGIN
DECLARE #pris varchar(2)
DECLARE #forventet varchar(2)
DECLARE #smag varchar(2)
DECLARE #count varchar(30)
IF EXISTS(SELECT * FROM feedback where personID = #personID AND ean = #ean)
BEGIN
SELECT #pris = (SELECT CAST(pris AS varchar(2)) FROM feedback where personID = #personID AND ean = #ean)
SELECT #forventet = (SELECT CAST(forventet AS varchar(2)) FROM feedback where personID = #personID AND ean = #ean)
SELECT #smag = (SELECT CAST(smag AS varchar(2)) FROM feedback where personID = #personID AND ean = #ean)
SELECT #ratingschars = #pris + #forventet + #smag
END
ELSE
BEGIN
SELECT #pris = (SELECT CAST(avg(pris) AS varchar(2)) FROM feedback WHERE ean = #ean)
SELECT #forventet += (SELECT CAST(avg(forventet) AS varchar(2)) FROM feedback WHERE ean = #ean)
SELECT #smag += (SELECT CAST(avg(smag) AS varchar(2)) FROM feedback WHERE ean = #ean)
SELECT #count += (SELECT CAST(count(*) AS varchar(30)) FROM feedback WHERE ean = #ean)
SELECT #ratingschars = #pris + #forventet + #smag + #count
END
END
COMMIT TRAN
Which I've tried to change to output of to int, with the same error results.
I'm stumped - I need help.
Stored-procedure has three parameters where as in your code, you've added only two parameters. So add a third parameter as OutPut type.
EDIT:
Stored Procedure:
ALTER PROCEDURE SampleProc
#no1 int,
#no2 int,
#result int OUTPUT
AS
set #result=#no1+#no2
RETURN
Code to execute the Stored-procedure:
cmd.CommandText = "SampleProc"
cmd.CommandType = CommandType.StoredProcedure
cmd.Connection = cn
Dim no1 as New OleDbParameter("#no1", OleDbType.Integer)
Dim no2 as New OleDbParameter("#no2", OleDbType.Integer)
Dim resultas New OleDbParameter("#result", OleDbType.Integer)
result.Direction = ParameterDirection.Output
no1.Value = 10
no2.Value = 20
cmd.Parameters.Add(no1)
cmd.Parameters.Add(no2)
cmd.Parameters.Add(result)
cn.Open()
cmd.ExecuteNonQuery()
cn.Close()
Dim returnResult as Integer
returnResult=CType(result.Value,Integer)
can you try the following?
command.Parameters.AddWithValue("#personID", personID);
command.Parameters.AddWithValue("#ean", ean);
Also, IF EXISTS(...) ... ELSE ... can be replaced with:
IF EXISTS(SELECT * FROM feedback where personID = #personID AND ean = #ean)
BEGIN
SELECT #ratingschars
= CAST(pris AS varchar(2))
+ CAST(forventet AS varchar(2))
+ CAST(smag AS varchar(2))
FROM feedback
WHERE personID = #personID
AND ean = #ean
END
ELSE
BEGIN
SELECT #ratingschars
= CAST(avg(pris) AS varchar(2)) --or STR
+ CAST(avg(forventet) AS varchar(2)) --or STR
+ CAST(avg(smag) AS varchar(2)) --or STR
+ CAST(count(*) AS varchar(11))
FROM feedback
WHERE ean = #ean
END
END
or
SELECT #ratingschars --Question: all these columns (pris, forventet, smag) are NOT NULL ?
= CAST(pris AS varchar(2))
+ CAST(forventet AS varchar(2))
+ CAST(smag AS varchar(2))
FROM feedback
WHERE personID = #personID
AND ean = #ean
IF #ratingschars IS NULL
BEGIN
SELECT #ratingschars
= CAST(avg(pris) AS varchar(2))
+ CAST(avg(forventet) AS varchar(2))
+ CAST(avg(smag) AS varchar(2))
+ CAST(count(*) AS varchar(30))
FROM feedback
WHERE ean = #ean
END