How we can make a store procedure in between time?
like,
Total Hr=(( outtime - intime) - (breakin time - breakout time) )
create procedure sp_time_outtime
#id bigint
as
begin
declare
#totalhour as nvarchar(50),
#tth as bigint,
#ttm as bigint,
#inhour as bigint,
#outhour as bigint,
#breakinhour as bigint select #tth = datediff(mi, intime, (case when breakouttime is null then isnull(breakintime,GETDATE()) else GETDATE() end) ) from time where empid=#id and CONVERT(date,GETDATE()) = CONVERT(date,[date])
select #ttm = datediff(mi, isnull(breakintime,'1/1/1990'),ISNULL(breakouttime,isnull (breakintime,'1/1/1990'))) from time where empid=#id and CONVERT(date,GETDATE()) = CONVERT(date,[date])
select #totalhour = (#tth -#ttm)
SET #totalhour = CASE WHEN (#tth -#ttm) >= 60 THEN (SELECT CAST(((#tth -#ttm) / 60) AS VARCHAR(2)) + ' :H :' +
CASE WHEN ((#tth -#ttm) % 60) > 0 THEN
CAST(((#tth -#ttm) % 60) AS VARCHAR(2)) + ' M'
ELSE
''
END) ELSE
CAST(((#tth -#ttm) % 60) AS VARCHAR(2)) + 'M'
END
if ((select outtime from time where empid=#id and convert(date,GETDATE())=CONVERT(date,[date])) IS NULL)
begin
update time set outtime=GETDATE(),totalhour=#totalhour where
empid=#id and CONVERT(date,GETDATE()) = CONVERT(date,[date])
end END
Related
I need help on optimizing this query that retrieves a list of products from businesses. This query only brings set of data using specific parameters you see below. It takes about 6-9 seconds to run with about 40,000 products and only brings 10 products at a time, but I need to make it faster.
I execute this:
EXEC [GetProducts] #StartRowIndex=0, #MaximumRows=10,
#SortedBy='ProductName', #SortedIn='DESC', #CategoryID=0,
#CategoryIDPath=N'''1|%''', #SearchText='ALL', #SearchSQL=N'', #CreatedByUser=0
Here's the full query:
ALTER PROCEDURE [GetProducts] (
#StartRowIndex int,
#MaximumRows int,
#SortedBy nvarchar(20),
#SortedIn nvarchar(6),
#CategoryID int,
#CategoryIDPath nvarchar(500),
#SearchText nvarchar(255),
#SearchSQL nvarchar(MAX),
#CreatedByUser int
)
as
BEGIN
--get correct Sorted By
DECLARE #strSortedBy nvarchar(300)
SET #strSortedBy =
(CASE
WHEN (#SortedBy = 'CreatedDate') THEN 'Products.CreatedDate ' + #SortedIn
WHEN (#SortedBy = 'Views') THEN 'Products.Views ' + #SortedIn
ELSE 'Products.ProductName ' + #SortedIn
END)
--check if you are filtering by Category START
DECLARE #FilterByCategoryID nvarchar(250)
IF (#CategoryID > 0)
BEGIN
SET #FilterByCategoryID = 'AND Products.CategoryID = ' + cast(#CategoryID as nvarchar(5))
END
else
BEGIN
IF (#CategoryIDPath <> '') --show category features first then the most recent by default
BEGIN
SET #FilterByCategoryID = 'AND Products.CategoryIDPath LIKE ' + #CategoryIDPath
END
else
BEGIN
SET #FilterByCategoryID = ''
END
END
--check if you are filtering by Category END
--this option is used when you are searching by category only START
IF (#SearchText <> '')
BEGIN
IF #SearchSQL = 'ALL'
BEGIN
SET #SearchSQL = ''
END
END
else
BEGIN
SET #SearchSQL = ''
END
--this option is used when you are searching by category only END
--check if you are filtering by CreatedByUser START
DECLARE #FilterByCreatedByUser nvarchar(250)
IF (#CreatedByUser > 0)
BEGIN
SET #FilterByCreatedByUser = 'AND Products.CreatedByUser = ' + cast(#CreatedByUser as nvarchar(10))
END
else
BEGIN
SET #FilterByCreatedByUser = ''
END
--check if you are filtering by CreatedByUser END
DECLARE #MaximumRow int
SET #MaximumRow = #startRowIndex + #maximumRows
exec('SELECT
RowRank
,Products.ItemID
,Products.ProductName
,Products.Description
,Products.CategoryID
,Products.CategoryIDPath
,Products.FileName
,Products.CategoryName
,Businesses.BusinessName
,Businesses.Country
,Products.TotalCount
FROM
(
SELECT
ROW_NUMBER() OVER(ORDER BY ' + #strSortedBy + ') AS RowRank
,COUNT(*) OVER() AS TotalCount
,Products.*
FROM
Products
INNER JOIN Businesses
ON Products.CreatedByUser = Businesses.CreatedByUser
AND Businesses.Published <> 0
AND (Businesses.[ExpireDate] >= GetDate() or Businesses.[ExpireDate] is null)
WHERE
Products.Published <> 0
AND (Products.[ExpireDate] >= GetDate() OR Products.[ExpireDate] is null)
AND Products.ItemType = ''Classifieds''
' + #FilterByCategoryID + '
' + #FilterByCreatedByUser + '
' + #SearchSQL + '
) AS Products
INNER JOIN Businesses
ON Products.CreatedByUser = Businesses.CreatedByUser
AND Businesses.Published <> 0
AND (Businesses.[ExpireDate] >= GetDate() or Businesses.[ExpireDate] is null)
WHERE
RowRank > ' + #startRowIndex + ' AND RowRank <= ' + #MaximumRow + '
ORDER BY ' + #strSortedBy)
END
i have a stored procedure in which i am getting error 'Unclosed quotation mark after the character string ' having a hard time with the script. please help me to find out what is wrong in my code.
here is my code.
ALTER PROCEDURE [dbo].[usp_Transfer]
#orgid bigint,
#SearchString nvarchar (500) = null,
#LocationId bigint = 0,
#ownerid bigint,
#OrderList varchar(MAX)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.\
SET NOCOUNT ON;
DECLARE #SQL varchar(MAX)
BEGIN
SET #SQL = 'SELECT ProductID = ii.ProductId,
InvItemId = convert(bigint,0),Name = p.Name,
PrimaryImageID = p.PrimaryImageID,ProductNumberLabel = p.ProductNumberLabel,ProductNumber = p.ProductNumber,
category = isnull(c.Name,''),
qty = ISNULL((SUM(ii.[QuantityOnHand]) - SUM(ii.[QuantitySold])), 0.00),
SalePrice= ISNULL(p.SalePrice, 0.00),
EnteredQuantity=(case when (ISNULL((SUM(ii.[QuantityOnHand]) - SUM(ii.[QuantitySold])), 0.00) > 1) then 1.00 else ISNULL((SUM(ii.[QuantityOnHand]) - SUM(ii.[QuantitySold])), 0.00) end)
,Discount=0,u.UnitName,
u.UnitID
FROM dbo.[Inven] ii
Left Join dbo.[Product] p on ii.ProductId = p.ProductId and p.activestatus=1
Left Join dbo.[category] c on p.DefaultCategoryId = c.CategoryId
Left Join dbo.[Unit] u on p.UnitId=u.UnitId and u.Activestatus=1
WHERE p.OrganizationID = #orgid
AND ii.InventoryID IN(1634)
AND ii.ActiveStatus = 1
AND p.ActiveStatus = 1
AND p.IsDisabled = 0
And p.CanSale = 1
AND ii.InventoryID IN (' + #OrderList + ')
group by ii.ProductId, p.Name, p.PrimaryImageID, p.ProductNumberLabel, p.ProductNumber, c.Name,p.SalePrice,u.unitname,u.UnitID
having ISNULL((SUM(ii.[QuantityOnHand]) - SUM(ii.[QuantitySold])), 0) > 0
Order by p.ProductNumber, p.Name, c.Name '
--EXEC(#SQL)
PRINT(#SQL)
END
END
Two things of note.
First, does #OrderList contain any quotes?
Second, this line:
...' WHERE p.OrganizationID = #orgid '
Should be:
....'WHERE p.OrganizationID = ' + #orgid + '...'
The easy way to test if either of these are the cause of the problem is to comment both out, run it and see if it works, if it does then comment them in one at a time to see which one gives you the error.
Finally, you could rewrite this query and avoid using a dynamic query at all. I guess looking at the query you have done it because of the IN (' + #OrderList + ') clause. These posts might help you rework that section:
Parameterize an SQL IN clause
SQL Server - In clause with a declared variable
Update your SP as below:
Note: there are so many errors if solve one like quotation mark, declare variable #orgid and then conversion error
Your initial error due to : category = isnull(c.Name,''), replace it with category = isnull(c.Name,'''')
alter PROCEDURE [dbo].[usp_Transfer]
#orgid bigint=1,
#SearchString nvarchar (500) = null,
#LocationId bigint = 0,
#ownerid bigint=1,
#OrderList varchar(MAX)='1'
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.\
SET NOCOUNT ON;
DECLARE #SQL varchar(MAX)
BEGIN
SET #SQL = 'SELECT ProductID = ii.ProductId,
InvItemId = convert(bigint,0),Name = p.Name,
PrimaryImageID = p.PrimaryImageID,ProductNumberLabel = p.ProductNumberLabel,ProductNumber = p.ProductNumber,
category = isnull(c.Name,''''),
qty = ISNULL((SUM(ii.[QuantityOnHand]) - SUM(ii.[QuantitySold])), 0.00),
SalePrice= ISNULL(p.SalePrice, 0.00),
EnteredQuantity=(case when (ISNULL((SUM(ii.[QuantityOnHand]) - SUM(ii.[QuantitySold])), 0.00) > 1) then 1.00 else ISNULL((SUM(ii.[QuantityOnHand]) - SUM(ii.[QuantitySold])), 0.00) end)
,Discount=0,u.UnitName,
u.UnitID
FROM dbo.[Inven] ii
Left Join dbo.[Product] p on ii.ProductId = p.ProductId and p.activestatus=1
Left Join dbo.[category] c on p.DefaultCategoryId = c.CategoryId
Left Join dbo.[Unit] u on p.UnitId=u.UnitId and u.Activestatus=1
WHERE p.OrganizationID = '+CAST(#orgid AS VARCHAR(10))+'
AND ii.InventoryID IN(1634)
AND ii.ActiveStatus = 1
AND p.ActiveStatus = 1
AND p.IsDisabled = 0
And p.CanSale = 1
AND ii.InventoryID IN (' + #OrderList + ')
group by ii.ProductId, p.Name, p.PrimaryImageID, p.ProductNumberLabel, p.ProductNumber, c.Name,p.SalePrice,u.unitname,u.UnitID
having ISNULL((SUM(ii.[QuantityOnHand]) - SUM(ii.[QuantitySold])), 0) > 0
Order by p.ProductNumber, p.Name, c.Name '
EXEC(#SQL)
PRINT(#SQL)
END
END
have a function below that returns a cursor. However I need it to return just one row. I have read on google about returning the data as a %rowtype but I do not seem to be able to get it to work.
The reason I don't want a cursor returned is that when I select the function one cell is returned saying (cursor) instead of displaying one row with 4 columns of data.
create or replace function udf
(
i_ptf_code in varchar2
,i_begin_date in date
,i_end_date in date
)
return sys_refcursor
is
portf_code varchar2(50);
end_date date;
chain_linked_ptf_net float;
chain_linked_ptf_gross float;
chain_linked_bmk float;
end_mv float;
v_cursor sys_refcursor;
cursor c_return_series is
select p.portf_code
,gpr.end_date
,gpr.end_market_value
,gpr.portf_perf_gross as gross_ret
,gpr.portf_perf_net as net_ret
,(exp(sum(ln(1 + gpr.portf_perf_gross)) over (partition by p.portf_code order by end_date)) - 1) as chain_linked_ptf_gross
,(exp(sum(ln(1 + gpr.portf_perf_net)) over (partition by p.portf_code order by end_date)) - 1) as chain_linked_ptf_net
,(exp(sum(ln(1 + gpr.bmk_perf)) over (partition by p.portf_code order by end_date)) - 1) as chain_linked_bmk
from portfolio_returns gpr
inner join portfolio p on p.portf_id = gpr.portf_id and p.is_composite != 2 --2 means composite
where p.portf_code = i_ptf_code
and gpr.end_date between i_begin_date and i_end_date;
begin
select i_ptf_code, i_end_date into portf_code, end_date from dual;
for c1line in c_return_series loop
if c1line.end_date = i_end_date then
select c1line.chain_linked_ptf_gross
,c1line.chain_linked_ptf_net
,c1line.chain_linked_bmk
,c1line.end_market_value
into chain_linked_ptf_gross
,chain_linked_ptf_net
,chain_linked_bmk
,end_mv
from dual;
end if;
end loop;
open v_cursor for
select portf_code as portf_code
,end_date as end_date
,chain_linked_ptf_gross * 100 as period_ptf_gross
,chain_linked_ptf_net * 100 as period_ptf_net
,chain_linked_bmk * 100 as period_bmk
,end_mv * 100 as period_mv
from dual;
return v_cursor;
close v_cursor;
end;
/
I am a little lost but I think this is what you need:
[...]
open v_cursor for
select portf_code as portf_code
,end_date as end_date
,chain_linked_ptf_gross * 100 as period_ptf_gross
,chain_linked_ptf_net * 100 as period_ptf_net
,chain_linked_bmk * 100 as period_bmk
,end_mv * 100 as period_mv
from dual;
return v_cursor;
-- close v_cursor; -- not needed
end;
-
DECLARE
l_rc SYS_REFCURSOR;
l_portf_code VARCHAR2(30);
l_end_date VARCHAR2(30);
l_period_ptf_gross NUMBER;
l_period_ptf_net NUMBER;
l_period_bmk NUMBER;
l_period_mv NUMBER;
BEGIN
l_rc := udf; -- This returns an open cursor
fetch v_rc into l_portf_code, l_end_date, l_period_ptf_gross, l_period_ptf_net, l_period_bmk, l_period_mv;
DBMS_OUTPUT.PUT_LINE
(
l_portf_code || ' ' ||
l_end_date || ' ' ||
l_period_ptf_gross || ' ' ||
l_period_ptf_net || ' ' ||
l_period_bmk || ' ' ||
l_period_mv
);
CLOSE v_rc;
END;
I am writing a report based on parameters, utilizing a sql stored procedure. Problem is there are several 'optional' parameters, where the user can choose a value, or ignore that parameter altogether. I need to use the stored proc as a dataset in asp.net report. Only way I thought of doing it is to create a table from the results. But I'm clueless.
How do I turn this into a 'create table' stored proc?
Any assistance is greatly appreciated.
Cindy
This is what I have so far -
ALTER PROCEDURE [dbo].[rspSCL]
-- Add the parameters for the stored procedure here
(#year as int,
#RRID as int,
#State as nchar(2),
#Sub as varchar(75),
#app as int,
#sprayed as int,
#subcontracted as int,
#thirdapp as bit)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
DECLARE #SQL as varchar(4000)
DECLARE #SUBQ AS varchar(400)
--what fields need to be seen
SET #SQL = 'SELECT C.CRID, C.DOT, C.RR, C.Pref, C.MP, C.Division, C.Subdivision,C.City, C.Street,
C.State, C.County, C.RestrictedCounty, C.Remarks, C.SpecialInstructions, C.Route, C.ThirdAppRequired,
C.MainTrks, C.OtherTrks, C.OnSpur, C.MaxSpeed, C.SubContracted, C.FenceEncroachment, C.Lat, C.Long,
C.PropertyType, C.WarningDevice,C.Surface, C.ROWNE, C.ROWNW, C.ROWSE, C.ROWSW, C.ROWWidth, C.ExtNE,
C.ExtNW, C.ExtSE, C.ExtSW, C.TempActive, A.Spray, A.ContractYear'
SET #SUBQ =
CASE WHEN #app = 1 THEN
'FROM Crossings LEFT OUTER JOIN
(select A.CRID, A.spray FROM ApplicationData A
WHERE A.ContractYear = ' + CAST( #year AS varchar(4)) + ') as APPS
ON Crossings.CRID = APPS.CRID'
WHEN #app = 2 THEN
'FROM Crossings inner join
(SELECT crid, C,OUNT(APPID)as count
from ApplicationData
where ContractYear = ' + CAST( #year AS varchar(4)) + '
group by CRID) as APPS
ON Crossings.CRID = APPS.CRID
WHERE Crossings.RR = '+ CAST( #RRID AS varchar(4)) + '
and crossings.state = '+ #state + '
and count = 1'
when #app = 3 THEN
'FROM Crossings inner join
(SELECT crid, COUNT(APPID)as count
from ApplicationData
where ContractYear = ' + CAST( #year AS varchar(4)) + '
group by CRID) as APPS
ON Crossings.CRID = APPS.CRID
WHERE Crossings.RR = '+ CAST( #RRID AS varchar(4)) + '
and crossings.state = '+ #state + '
and count = 2'
ELSE ''
END
--add the FROM to the query
SET #SQL = #SQL + #SUBQ
--add the subdivision to the where statement
If #Sub != 'ALL'
SET #SQL = #SQL + 'AND (C.Subdivision = ' + #Sub + ')'
ELSE
SET #SQL = #SQL
--add sprayed to where
DECLARE #S as varchar(100)
SET #S =
CASE WHEN #sprayed = 1 THEN
'AND (A.sprayed = 1)'
WHEN #sprayed = 0 THEN
'AND (A.sprayed = 0)'
ELSE
''
END
SET #SQL = #SQL + #S
--add subcontracted to where
DECLARE #C as varchar (100)
SET #C =
CASE WHEN #subcontracted = 0 THEN
'AND (C.subcontracted = 0)'
WHEN #subcontracted = 1 THEN
'AND (C.subcontracted = 1)'
ELSE
''
END
SET #SQL = #SQL + #C
IF #thirdapp = 1
SET #SQL = #SQL + 'AND (C.ThirdAppRequired = 1)'
ELSE
SET #SQL = #SQL
END
I have a asp:GridView with datasource like List
I added custom paging, using a procedure, when i use the procedure in MS SERVER Management
Studio its performance is fast, as soon as i try it in asp.net, performance is awful during
pagination.
The 1st step (when the gridview fills) is very fast, but when i am starting to paginate,
the performance kills, i am waiting 5-25 seconds for passing to the next page.
Dear all, what must i do to solve this problem, will you help me ?
HERE IS THE STORED PROCEDURE
CREATE PROCEDURE [sp_QS]
#startRowIndex INT,
#maximumRows INT,
#afterWhere NVARCHAR(MAX),
#sortBy NVARCHAR(MAX),
#totalRows INT OUT
AS
SET NOCOUNT ON;
DECLARE #P NVARCHAR(MAX), #Q1 NVARCHAR(MAX), #Q2 NVARCHAR(MAX)
DECLARE #first_id INT
SET #startRowIndex = (#startRowIndex - 1) * #maximumRows
SET #Q1 = 'query part 1'
SET #Q2 = 'query part 2'
IF #startRowIndex = 0
BEGIN
SET #startRowIndex = 1
END
SET ROWCOUNT #startRowIndex
SET #P = 'SET NOCOUNT ON; DECLARE #out INT SELECT #out = id FROM table1 ' + #Q2 + '
WHERE ' + #afterWhere + ' SELECT #out'
IF OBJECT_ID('tempdb..#t1','u') IS NOT NULL
BEGIN
DROP TABLE #t1
END
CREATE TABLE #t1 (col INT)
INSERT #t1 EXEC(#P)
SELECT #first_id = col FROM #t1
DROP TABLE #t1
--SELECT #first_id AS FFFF --PRINT #first_id
SET ROWCOUNT #maximumRows
SET #P = 'SET NOCOUNT ON;' + 'SELECT ' + #Q1 + ' FROM table ' + #Q2 + ' WHERE (id >=' +
CAST(#first_id AS NVARCHAR(60)) + ') AND (' + #afterWhere + ') ' + #sortBy
EXEC(#P)
SET ROWCOUNT 0
-- GET THE TOTAL ROWS
IF #startRowIndex = 1
BEGIN
SET #P = 'SET NOCOUNT ON;' + 'SELECT COUNT(id) FROM table1 ' + #Q2 + ' WHERE ' +
#afterWhere
IF OBJECT_ID('tempdb..#t2','u') IS NOT NULL
BEGIN
DROP TABLE #t2
END
CREATE TABLE #t2 (col INT)
INSERT #t2 EXEC (#P)
SELECT #totalRows = col FROM #t2
DROP TABLE #t2
SELECT #totalRows AS QueryResultRowCount
END
GO
AND HERE IS THE CODE IN ASP.NET(WITH C#)
private void BindData()
{
string connectionString = "Server=localhost;" +
"Database=Northwind;Trusted_Connection=true";
SqlConnection myConnection = new SqlConnection(connectionString);
SqlCommand myCommand = new SqlCommand("usp_GetProducts",
myConnection);
myCommand.CommandType = CommandType.StoredProcedure;
myCommand.Parameters.AddWithValue("#startRowIndex",
currentPageNumber);
myCommand.Parameters.AddWithValue("#maximumRows", PAGE_SIZE);
myCommand.Parameters.Add("#totalRows", SqlDbType.Int, 4);
myCommand.Parameters["#totalRows"].Direction =
ParameterDirection.Output;
SqlDataReader sqlReader = myCommand.ExecuteReader();
while(sqlReader.Read())
{
// filling List<> object to bind to gridview as datasource
}
...
}
I have to buttons 'next' and 'prvious', pressing these buttons, i am changing
currentPageNumber with + or - 1, calling BindData() method after it.
Thanks in advance
That's an SQL against the AdventureWorks database from SQL Server 2005 samples:
DECLARE
#FirstRow int,
#LastRow int,
#Sorting varchar(50);
Declare #SelectClause nvarchar(max),
#Params nvarchar(MAX);
SELECT #FirstRow = 1, #LastRow = 10;
SELECT #SelectClause = 'WITH CTE AS (
SELECT
ROW_NUMBER() OVER ( ORDER BY ' + COALESCE(#Sorting, 'SalesOrderID ASC') + ' ) AS RowNumber,
COUNT(*) OVER() AS TotalRows,
SalesOrderID,
OrderDate,
DueDate,
CASE OnlineOrderFlag WHEN 1 THEN ''Yes'' ELSE ''No'' END as OnlineOrderFlagString
FROM
Sales.SalesOrderHeader
WHERE
SubTotal > 100)
SELECT * FROM CTE WHERE RowNumber >= #FirstRow AND RowNumber < #LastRow',
#Params = '#FirstRow int, #LastRow int';
exec sp_executesql
#statement = #SelectClause,
#params = #Params,
#FirstRow = #FirstRow,
#LastRow = #LastRow;
After you have execute query you can fetch total rows value from first row if exists. Note, that if you must provide ability to sort by computed columns like the OnlineOrderFlagString, the query will become bit more complex:
DECLARE
#FirstRow int,
#LastRow int,
#Sorting varchar(50);
Declare #SelectClause nvarchar(max),
#Params nvarchar(MAX);
SELECT #FirstRow = 1, #LastRow = 10, #Sorting = 'OnlineOrderFlagString ASC'
SELECT #SelectClause = 'WITH CTE_1 AS (
SELECT
SalesOrderID,
OrderDate,
DueDate,
CASE OnlineOrderFlag WHEN 1 THEN ''Yes'' ELSE ''No'' END as OnlineOrderFlagString
FROM
Sales.SalesOrderHeader
WHERE
SubTotal > 100),
CTE_2 AS (
SELECT
ROW_NUMBER() OVER ( ORDER BY ' + COALESCE(#Sorting, 'SalesOrderID ASC') + ' ) AS RowNumber,
COUNT(*) OVER() AS TotalRows,
SalesOrderID,
OrderDate,
DueDate,
OnlineOrderFlagString
FROM
CTE_1
)
SELECT * FROM CTE_2 WHERE RowNumber >= #FirstRow AND RowNumber < #LastRow',
#Params = '#FirstRow int, #LastRow int';
exec sp_executesql
#statement = #SelectClause,
#params = #Params,
#FirstRow = #FirstRow,
#LastRow = #LastRow;