I create this function to calculate shortage material quantity
ALTER FUNCTION [dbo].[ReturnShortageByItemCodeLinePackage]
(#lineId int, #testpackId int, #MaterialDescriptionId int)
RETURNS float
AS BEGIN
DECLARE #shortageQuantity float
DECLARE #MIVQuantity float
DECLARE #totalQuantity float
DECLARE #spoolQuantity float
DECLARE #ExistInSiteQuantity float
DECLARE #BeforeDoneQuantity float
SELECT
#totalQuantity = Quantity,
#spoolQuantity = QuantitySpool,
#ExistInSiteQuantity = QuantityExistInSite,
#BeforeDoneQuantity = QuantityBeforeDone
FROM
[SPMS2].[dbo].Materials
WHERE
LineId = #lineId
AND TestPackageId = #testpackId
AND MaterialDescriptionId = #MaterialDescriptionId
SELECT
#MIVQuantity = SUM(QuantityDeliver)
FROM
MaterialIssueVoucherDetails miv
JOIN
MaterialRequestContractorDetails mrc ON miv.MaterialRequestContractorDetailId = mrc.Id
WHERE
TestPackageId = #testpackId
AND LineId = #lineId
AND miv.MaterialDescriptionId = #MaterialDescriptionId
IF #MIVQuantity IS NULL
BEGIN
SET #MIVQuantity = 0
END
SET #shortageQuantity = #totalQuantity - (#BeforeDoneQuantity + #ExistInSiteQuantity + #spoolQuantity + #MIVQuantity)
RETURN round(#shortageQuantity,3)
END
I use this function inside my stored procedure as you can see here:
ALTER PROCEDURE [dbo].[SPViewMTO]
AS
BEGIN
SELECT
dbo.Lines.Unit, dbo.Lines.LineNumber, dbo.Lines.DocumentNumber,
dbo.BaseMaterials.Name AS MaterialName,
dbo.MaterialDescriptions.Name AS MaterialDescription,
dbo.MaterialDescriptions.Description, dbo.MaterialScopes.ScopeName,
dbo.MaterialScopeObjectNames.ObjectName,
dbo.MaterialDescriptions.Size1, dbo.MaterialDescriptions.Size2,
dbo.MaterialDescriptions.ItemCode,
dbo.Materials.Quantity, dbo.Materials.Discipline, dbo.Materials.Id,
dbo.Lines.Id AS LineId, dbo.Materials.QuantitySpool,
dbo.Materials.QuantityExistInSite, dbo.Materials.QuantityBeforeDone,
dbo.TestPackages.PackageNumber, dbo.Materials.TestPackageId,
ISNULL(dbo.ReturnShortageByItemCodeLinePackage(Lines.Id, TestPackageId, MaterialDescriptionId), 0) AS Shortage
FROM
dbo.Materials
INNER JOIN
dbo.Lines ON dbo.Materials.LineId = dbo.Lines.Id
INNER JOIN
dbo.BaseMaterials ON dbo.Lines.BaseMaterialId = dbo.BaseMaterials.Id
INNER JOIN
dbo.MaterialDescriptions ON dbo.Materials.MaterialDescriptionId = dbo.MaterialDescriptions.Id
INNER JOIN
dbo.MaterialScopes ON dbo.MaterialDescriptions.MaterialScopeId = dbo.MaterialScopes.Id
INNER JOIN
dbo.MaterialScopeObjectNames ON dbo.MaterialDescriptions.MaterialScopeObjectId = dbo.MaterialScopeObjectNames.Id
INNER JOIN
dbo.TestPackages ON dbo.Materials.TestPackageId = dbo.TestPackages.Id
END
The time execution of the stored procedure is about 47 seconds inside my SQL Server Management Studio directly, but when I call the stored procedure` from my C# application I get this error:
timeout expired the timeout period elapsed SQL Server 2012
Here is my code to call the stored procedure:
lst = _ctx.Database.SqlQuery<ViewDomainClass.MaterialOffice.DAViewMTO>
("EXEC [dbo].SPViewMTO").ToList();
Timeout is a property of connection string in ADO.Net and other Frameworks like LINQ & EF.
Try to change timeout in your connection string as you want.
Also you can set time out on SQLCommand to override timeout property.
You use (NOLOCK) you can increase performance your query.
ALTER PROCEDURE [dbo].[SPViewMTO]
AS
BEGIN
SELECT dbo.Lines.Unit, dbo.Lines.LineNumber, dbo.Lines.DocumentNumber, dbo.BaseMaterials.Name AS MaterialName,
dbo.MaterialDescriptions.Name AS MaterialDescription, dbo.MaterialDescriptions.Description, dbo.MaterialScopes.ScopeName,
dbo.MaterialScopeObjectNames.ObjectName, dbo.MaterialDescriptions.Size1, dbo.MaterialDescriptions.Size2, dbo.MaterialDescriptions.ItemCode,
dbo.Materials.Quantity, dbo.Materials.Discipline, dbo.Materials.Id, dbo.Lines.Id AS LineId, dbo.Materials.QuantitySpool, dbo.Materials.QuantityExistInSite,
dbo.Materials.QuantityBeforeDone, dbo.TestPackages.PackageNumber, dbo.Materials.TestPackageId,isnull(dbo.ReturnShortageByItemCodeLinePackage(Lines.Id,TestPackageId,MaterialDescriptionId),0) As Shortage
FROM dbo.Materials(NOLOCK) INNER JOIN
dbo.Lines(NOLOCK) ON dbo.Materials.LineId = dbo.Lines.Id INNER JOIN
dbo.BaseMaterials(NOLOCK) ON dbo.Lines.BaseMaterialId = dbo.BaseMaterials.Id INNER JOIN
dbo.MaterialDescriptions(NOLOCK) ON dbo.Materials.MaterialDescriptionId = dbo.MaterialDescriptions.Id INNER JOIN
dbo.MaterialScopes(NOLOCK) ON dbo.MaterialDescriptions.MaterialScopeId = dbo.MaterialScopes.Id INNER JOIN
dbo.MaterialScopeObjectNames(NOLOCK) ON dbo.MaterialDescriptions.MaterialScopeObjectId = dbo.MaterialScopeObjectNames.Id INNER JOIN
dbo.TestPackages(NOLOCK) ON dbo.Materials.TestPackageId = dbo.TestPackages.Id
EnD
Related
I want to filter data on conditions using combo boxes in c#, so I used this stored procedure:
CREATE PROCEDURE [dbo].[GET_FIXING_ON_CONDITIONS]
#BranchID int,
#MachGroupID int,
#FailGroupID int,
#FailID int,
#MachNo varchar(50),
#DateFrom date,
#DateTO date
AS
SELECT tbBranches.BranchName,
tbMachines.MachNo,
tbMachines.MachType,
tbMachinesGroups.MachGroupName,
tbFails.FailName,
tbFailsGroups.FailGroupName,
tbFailsType.FailTypeName,
tbFixing.FixDate,
tbFixing.FixDetails,
tbFixing.FixPerson
FROM tbMachines
INNER JOIN tbFixing ON tbMachines.MachNo = tbFixing.FixMachNo
AND tbMachines.BranchID = tbFixing.BranchID
INNER JOIN tbFailsGroups ON tbMachines.BranchID = tbFailsGroups.BranchID
INNER JOIN tbFailsType ON tbMachines.BranchID = tbFailsType.BranchID
INNER JOIN tbFails ON tbFixing.FixFailID = tbFails.FailID
AND tbFixing.BranchID = tbFails.BranchID
AND tbFailsGroups.FailGroupID = tbFails.FailGroupID
AND tbFailsGroups.BranchID = tbFails.BranchID
AND tbFailsType.FailTypeID = tbFails.FailType
AND tbFailsType.BranchID = tbFails.BranchID
INNER JOIN tbMachinesGroups ON tbMachines.MachGroupID = tbMachinesGroups.MachGroupID
AND tbMachines.BranchID = tbMachinesGroups.BranchID
INNER JOIN tbBranches ON tbMachines.BranchID = tbBranches.BranchID
AND tbFixing.BranchID = tbBranches.BranchID
WHERE tbBranches.BranchID = #BranchID
AND tbMachinesGroups.MachGroupID = #MachGroupID
AND tbFailsGroups.FailGroupID = #FailGroupID
AND tbFails.FailID = #FailID
AND tbMachines.MachNo = #MachNo
AND tbFixing.FixDate >= #DateFrom
AND tbFixing.FixDate <= #DateTO;
Parameters are compensated by the 7 combo boxes but the problem is I have to choose (all) parameters values to display the data and this is not required,
what I want is display data once I choose (any) value from any combo box
Most generally, you would do this by passing null to any parameter which has not been set by the user and the query follows this pattern:
WHERE (#BranchID IS NULL OR tbBranches.BranchID = #BranchID)
AND (MachGroupID IS NULL OR tbMachinesGroups.MachGroupID = #MachGroupID)
AND ...
It depends what you pass in your parameters if they are not specified in your C# app. (I personally pass NULLs in such a case).
I used to use a query structure like this:
SELECT ...
WHERE
(#Param1 IS NULL OR [Value1] = #Param1) AND
(#Param2 IS NULL OR [Value2] = #Param2) AND
...
Well, I was watching a video tutorial on youtube about making a program with c# and using a database. The guy was using SQL commands while I was using MySQL through phpmyadmin (XAMPP is love).
I've managed to keep going until I reached one part where the guy was creating stored procedures and input this code:
create procedure datosfactura #NumFac int
as
select
F.*, D.PrecioVen, D.CanVe, C.Nom_cli, A.Nom_pro, D.PrecioVen * D.CanVe as importe
from
Facturas F inner join Detalles D on F.NunFac = D.NumFac
inner join Articula A on D.CodPro = A.id_pro
inner join Cliente C on F.CodCli = C.id_clientes
where F.NumFac = #NumFac
I racket my brain and tried different ways but I can figure out what I'm doing wrong.
As it is, if I make a new MySQL command inputting that query it returns that there's an error in the first line.
What is the right way to convert this SQL query into MySQL? Thank you for your help.
Try this:
delimiter //
create procedure datosfactura(NumFac int)
begin
select F.*,
D.PrecioVen,
D.CanVe,
C.Nom_cli,
A.Nom_pro,
D.PrecioVen * D.CanVe as importe
from Facturas F
inner join Detalles D on F.NunFac = D.NumFac
inner join Articula A on D.CodPro = A.id_pro
inner join Cliente C on F.CodCli = C.id_clientes
where F.NumFac = NumFac;
end//
delimiter ;
Useful articles:
http://www.mysqltutorial.org/getting-started-with-mysql-stored-procedures.aspx
https://dev.mysql.com/doc/refman/8.0/en/create-procedure.html
Maybe something like this (i dont have access to mysql now)
delimiter $$
create function datosfactura(IN NumFac int)
BEGIN
select
F.*, D.PrecioVen, D.CanVe, C.Nom_cli, A.Nom_pro, D.PrecioVen * D.CanVe as
importe
from
Facturas F inner join Detalles D on F.NunFac = D.NumFac
inner join Articula A on D.CodPro = A.id_pro
inner join Cliente C on F.CodCli = C.id_clientes
where F.NumFac = NumFac
end $$
I have three Tables :
tbl_Publisher [Publisher_ID, addr,account-num,...,city];
tbl_Title [Title_ID, frequency, publisher,.., Publisher_ID];
tbl_Invoice [Invoice_ID, ordered_Date,...,Title_ID];
I would like to return a list of Titles by Publisher and each Title has the count number of Invoices it contains. in one result set.
I'm using a stored procedure as following :
PROCEDURE [dbo].[usp_GetTitlesbyPublisher]
-- Add the parameters for the stored procedure here
#PublisherID INT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
-- Insert statements for procedure here
SELECT Title_ID,TitleName,pub_type,Frequency , Holdings ,tbl_Title.publisher ,section ,tbl_Title.Publisher_ID from tbl_Title, tbl_Publisher
where tbl_Title.Publisher_ID = tbl_Publisher.Publisher_ID
and #PublisherID = tbl_Publisher.Publisher_ID
END
How can I return the number of Invoice by each Title ?
You can probably accomplish this with a GROUP BY:
SELECT t.Title_ID, t.TitleName, p.pub_type,
t.Frequency, Holdings, t.publisher, section,
t.Publisher_ID, count(i.Invoice_ID) as NoOfInvoices
from tbl_Title t
inner join tbl_Publisher p on t.Publisher_ID = p.Publisher_ID
left join tbl_Invoice i on i.Title_ID = t.Title_ID
where #PublisherID = p.Publisher_ID
group by t.Title_ID, t.TitleName, p.pub_type, t.Frequency,
Holdings, t.publisher, section, t.Publisher_ID
Not checked the syntax on this.
SELECT COUNT(tbl_Invoice.Invoice_ID) 'InvoiceCount',Title_ID,TitleName,pub_type,Frequency, Holdings ,tbl_Title.publisher ,section ,tbl_Title.Publisher_ID
FROM tbl_Title
INNER JOIN tbl_Publisher ON tbl_Publisher.Publisher_ID = tbl_Title.Publisher_ID
INNER JOIN tbl_Invoice ON tbl_Invoice.Invoice_ID = tbl_Title.Invoice_ID
WHERE tbl_Publisher.Publisher_ID = #PublisherID
GROUP BY
Title_ID,TitleName,pub_type,Frequency, Holdings ,tbl_Title.publisher ,section ,tbl_Title.Publisher_ID
I have made a Sp with a single input parameter. I am trying to bind it with my webservice. But i am not sure how to call it inside my service and how to pass the input parameter. here is my sp
CREATE PROCEDURE StudentDetailss
#routeId varchar
AS
SELECT dbo.Users.FirstName, dbo.Users.LastName, dbo.PSS_Grades.GradeNo, dbo.PSS_Divisions.Name AS DivisionName, dbo.PSS_Stops.StopName,
dbo.PSS_ContactDeatils.Mobile, dbo.PSS_Routes.RouteId, dbo.PSS_Routes.RouteName, dbo.PSS_Students.StudentID, dbo.PSS_RelationShips.RelationshipID,
MIN(dbo.PSS_RelationShips.RelationTypeID) AS RelationTypeID, Users_1.FirstName AS ParentFname, Users_1.LastName AS ParentLname
FROM dbo.Users AS Users_1 INNER JOIN
dbo.PSS_ContactDeatils ON Users_1.UserID = dbo.PSS_ContactDeatils.UserID INNER JOIN
dbo.PSS_RelationShips INNER JOIN
dbo.Users ON dbo.PSS_RelationShips.StudentUserID = dbo.Users.UserID INNER JOIN
dbo.PSS_Routes INNER JOIN
dbo.PSS_Students INNER JOIN
dbo.PSS_Stops ON dbo.PSS_Students.StopId = dbo.PSS_Stops.StopId ON dbo.PSS_Routes.RouteId = dbo.PSS_Stops.RouteId ON dbo.Users.UserID = dbo.PSS_Students.StudentID AND
dbo.PSS_RelationShips.StudentUserID = dbo.PSS_Students.StudentID ON Users_1.UserID = dbo.PSS_RelationShips.RelatedUserID INNER JOIN
dbo.PSS_Grades INNER JOIN
dbo.PSS_StudentDivisions ON dbo.PSS_Grades.GradeID = dbo.PSS_StudentDivisions.GradeID INNER JOIN
dbo.PSS_Divisions ON dbo.PSS_Grades.GradeID = dbo.PSS_Divisions.GradeID AND dbo.PSS_StudentDivisions.DivisionID = dbo.PSS_Divisions.DivisionID ON
dbo.PSS_Students.StudentID = dbo.PSS_StudentDivisions.StudentUserID
WHERE PSS_Routes.RouteId=#routeId
GROUP BY dbo.Users.FirstName, dbo.Users.LastName, dbo.PSS_Grades.GradeNo, dbo.PSS_Divisions.Name, dbo.PSS_Stops.StopName, dbo.PSS_ContactDeatils.Mobile,
dbo.PSS_Routes.RouteId, dbo.PSS_Routes.RouteName, dbo.PSS_Students.StudentID, dbo.PSS_RelationShips.RelationshipID, Users_1.FirstName, Users_1.LastName
HAVING (MIN(dbo.PSS_RelationShips.RelationTypeID) <> 3)
I have done Function Import and created a complex Type out of this SP. Now i want to call it inside my Api. How can it be possible
If You have imported Your function it will be accesible via context object, like below:
public IEnumerable<StudentDetailss_result> GetStudentDetails(string routeId)
{
using(var ctx = new YourContextHere())
{
var result = ctx.StudentDetailss(routeId);
return result.ToList();
}
}
I am trying to use With in stored procedure
USE [BusOprtn]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[AddRepairedStock]
#RepairedItems [dbo].[RepairedItems] readonly
AS
BEGIN
declare #productNo bigint,#productManufacturer bigint
SET NOCOUNT ON;
begin try
begin transaction
UPDATE [BusOprtn].[dbo].[RepairItem] SET [ReturnedQuantity] = rdi.ReturnedQuantity,[AmountPaid] = rdi.AmountPaid,[ReturnDate] = rdi.ReturnDate from [BusOprtn].[dbo].[RepairItem] as ri inner join #RepairedItems as rdi on ri.id=rdi.id;
;with y as (
select [PartUsedId],rdi.[ReturnedQuantity] from [BusOprtn].[dbo].[RepairItem] as ri inner join #RepairedItems as rdi on ri.Id=rdi.id
), x as (
SELECT [PartNo] ,[ManufacturerId],[ReturnedQuantity] FROM [BusOprtn].[dbo].[PartUsed] as p inner join y
on p.id = y.PartUsedId
)
UPDATE [BusOprtn].[dbo].[ProductMaster] SET [RepairedStock] =( [RepairedStock]+x.[ReturnedQuantity]) from [BusOprtn].[dbo].[ProductMaster] as pm inner join x on x.[PartNo]=pm.Id;
UPDATE [BusOprtn].[dbo].[ProductStockManufacturer] SET [RepairedCurrentStock] = ([RepairedCurrentStock]+x.[ReturnedQuantity]) from [BusOprtn].[dbo].[ProductStockManufacturer] as pm inner join x on x.[PartNo]=pm.[ProductNo] and x.[ManufacturerId]= pm.[ManufacturerId];
commit transaction
end try
BEGIN CATCH
declare #ErrorMessage nvarchar(max), #ErrorSeverity
int, #ErrorState int;
select #ErrorMessage = ERROR_MESSAGE() + ' Line ' + cast
(ERROR_LINE() as nvarchar(5)), #ErrorSeverity = ERROR_SEVERITY(),
#ErrorState = ERROR_STATE();
rollback transaction;
raiserror (#ErrorMessage, #ErrorSeverity, #ErrorState);
END CATCH
END
When i execute above command it executes successfully. But when i try to call stored procedure at runtime it gives error
`Invalid object name 'x'.
Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 0, current count = 1.`
Earlier problem was with sub query as it not allowed with "WITH" so tried using another temp table y but error continued. I refereed Allowed Items for allowed items in WITH.
The error comes from the second update statement where you are using the CTE x
The scope for a CTE is one statement so x is only visible for the first update.
To fix this you can either duplicate the code for the CTE before the second update or you can use a temp table (or table variable) to capture the output from x and use the temp table in both your update statements instead of the CTE.
With a different formatting of the code this is easy to see.
First update statement:
with y as
(
select [PartUsedId],
rdi.[ReturnedQuantity]
from [BusOprtn].[dbo].[RepairItem] as ri
inner join #RepairedItems as rdi
on ri.Id=rdi.id
), x as
(
SELECT [PartNo],
[ManufacturerId],
[ReturnedQuantity]
FROM [BusOprtn].[dbo].[PartUsed] as p
inner join y
on p.id = y.PartUsedId
)
UPDATE [BusOprtn].[dbo].[ProductMaster]
SET [RepairedStock] = ([RepairedStock]+x.[ReturnedQuantity])
from [BusOprtn].[dbo].[ProductMaster] as pm
inner join x
on x.[PartNo]=pm.Id;
Second update statement:
UPDATE [BusOprtn].[dbo].[ProductStockManufacturer]
SET [RepairedCurrentStock] = ([RepairedCurrentStock]+x.[ReturnedQuantity])
from [BusOprtn].[dbo].[ProductStockManufacturer] as pm
inner join x
on x.[PartNo]=pm.[ProductNo] and x.[ManufacturerId]= pm.[ManufacturerId];
You can try to use SQL Server Profiler (Service menu in MSSMS). There you can find what query exactly received. Maybe something is different.
Hope it will help.