Development of a function that generates new work costs - sql

there is a problem with writing this function. I counted the number of works with the same name, but then I got stuck. The task itself sounds like this: Creating a function that generates a new cost of work. If the work has the same names, reduce their cost in proportion to their number
CREATE OR ALTER FUNCTION Новая_стоимость_работ
()
RETURNS #NewCoast TABLE(Код_работы INT,Наименование nvarchar(50),Стоимость_работы DECIMAL(18,2))
BEGIN
INSERT #NewCoast
SELECT Наименование, COUNT(*) AS Количество
FROM Работы
GROUP BY Наименование
HAVING COUNT(*) > 1
RETURN
END
Table
CREATE TABLE Работы
(Код_работы INT,
Наименование nvarchar(50) NOT NULL,
Стоимость_работы DECIMAL(18,2) NOT NULL,
CONSTRAINT PK2 PRIMARY KEY(Код_работы)
)

Related

Insert new record into autonumbered table, and then use the autonumber in another table

I'm writing a stored procedure to insert data from a form into two tables. One table has an autonumbered identity field. I need to insert the data into that table, find the newly created autonumber, and use that number to insert data into another table. So, to boil it down, I have a one-to-many link between the two tables and I need to make sure the identity field gets inserted.
Is this code the best way to do something like this, or am I missing something obvious?
CREATE PROCEDURE [dbo].[sp_Insert_CRT]
(
#TRACKING_ID int,
#CUST_NUM int,
#TRACKING_ITEM_ID int,
#STATEMENT_NUM nvarchar (200) = null,
#AMOUNT numeric (15, 2),
#BBL_ADJUSTED int = NULL,
#PAID_VS_BILLED int = NULL,
#ADJUSTMENT_TYPE int = NULL,
#ENTERED_BY nvarchar (10) = NULL,
#ENTERED_DATE date = NULL,
#AA_STATUS int = NULL
)
AS
BEGIN
-- Insert data into CRT_Main, where Tracking_ID is an autonumber field
INSERT into tbl_CRT_Main
(
-- TRACKING_ID
CUST_NUM
,TRACKING_ITEM_ID
,STATEMENT_NUM
,AMOUNT
)
VALUES
(
-- #TRACKING_ID
#CUST_NUM
,#TRACKING_ITEM_ID
,#STATEMENT_NUM
,#AMOUNT
)
-- Find the newly generated autonumber, and use it in another table
BEGIN TRANSACTION
DECLARE #TrackID int;
SELECT #TrackID = coalesce((select max(TRACKING_ID) from tbl_CRT_Main), 1)
COMMIT
INSERT into tbl_CRT_Admin_Adjustment
(
TRACKING_ID
,BBL_ADJUSTED
,PAID_VS_BILLED
,[ADJUSTMENT_TYPE]
,[ENTERED_BY]
,[ENTERED_DATE]
,AA_STATUS
)
VALUES
(
#TrackID
,#BBL_ADJUSTED
,#PAID_VS_BILLED
,#ADJUSTMENT_TYPE
,#ENTERED_BY
,#ENTERED_DATE
,#AA_STATUS
)
END
SELECT #TrackID = coalesce((select max(TRACKING_ID) from tbl_CRT_Main), 1)
No, don't do this. This will get you the maximum value of TRACKING_ID yes, but that doesn't mean that's the value that was created for your INSERT. If multiple INSERT statements were being run by different connections then very likely you would get the wrong value.
Instead, use SCOPE_IDENTITY to get the value:
SET #TrackID = SCOPE_IDENTITY();
Also, there is no need to wrap the above in an explicit transaction like you have with your SELECT MAX(). Instead, most likely, the entire batch in the procedure should be inside it's own explicit transaction, with a TRY...CATCH so that you can ROLLBACK the whole batch in the event of an error.

Not able to use LAG function in defining computed column in SQL Server 2014

I am trying to create table where I want computed column which will have column value from previous row from the same table. But I am not able to use LAG function successfully.
CREATE TABLE DYL(
DY_DT DATE NOT NULL,
DY_SEN_NME varchar(20) NOT NULL,
DY_OEN_PRC numeric(14,2) NOT NULL,
DY_HEL_PRC numeric(14,2) NOT NULL,
DY_LEL_PRC numeric(14,2) NOT NULL,
DY_CLN_PRC numeric(14,2) NOT NULL,
DY_REG AS (DY_HEL_PRC - DY_LEL_PRC) PERSISTED,
DY_PRV_PRC AS LAG(DY_CLN_PRC,1,0) OVER (PARTITION BY DY_SEN_NME ORDER BY DT)
)
I get error Windows Functions can only appear in SELECT or ORDER BY clauses.
If this is not possible then how can this be achieved using function. I tried writing a scalar function and associated it to DY_PRV_PRC.
ALTER TABLE DYL
ADD DY_PRV_PRC AS F_PRV_PRC()
but this is giving me same value in DY_PRV_PRC instead of giving previous row value of column DY_CLN_PRC
Below is the code for the Function F_PRV_PRC:
CREATE FUNCTION [dbo].[F_PRV_PRC] ()
RETURNS NUMERIC(14,2)
AS
BEGIN
DECLARE #pcp NUMERIC(14,2)
SELECT #pcp = LAG(DY_CLN_PRC,1,0) OVER (PARTITION BY DY_SEN_NME ORDER BY DY_DT)
FROM DYL;
RETURN #pcp;
END;
If possible, please suggest change to the function so it can give previous row column value. I am extremely sorry as I am new to SQL coding.
Many Thanks in advance
This is not really a good thing to do (from a performance perspective). But, if you wanted to do it, start with a user valued function:
DY_PRV_PRC AS (get_prev_value(DY_CLN_PRC, DY_SEN_NME, DT))
Then define the function something like this:
CREATE FUNCTION dbo.get_prev_value (
#DY_CLN_PRC numeric(14,2)
#DY_SEN_NME varchar(20)
#DT date
)
RETURNS NUMERIC(14,2)
AS
BEGIN
DECLARE #pcp NUMERIC(14,2)
SELECT #pcp = (SELECT TOP 1 DY_CLN_PRC
FROM DYL
WHERE DY_SEN_NME = #DY_SEN_NME
DY_DT < #DY_DT
ORDER BY DY_DT DESC
);
RETURN #pcp;
END;
If you want to use LAG() use a view:
create view v_dyl as
select dyl.*,
lag(DY_CLN_PRC) over (partition by DY_SEN_NME order by DT) as prev_dy_cln_prc
from dyl;

Firebird query result to CSV using Flamerobin

I am trying to export the data from a Firebird store procedure using a loop. I am using Flamerobin tool to do this. I get the results but the columns and rows are all messed up when I export them to csv file! All headers will be in one cell and values are all over the place! Is there any way to export the result to excel or csv file?
set term!!;
EXECUTE BLOCK RETURNS (
SOD_AUTO_KEY Integer,
CURRENCY_CODE Char(3),
SO_CATEGORY_CODE Char(10),
SO_NUMBER Char(12),
INVC_NUMBER Char(12),
ENTRY_DATE Timestamp,
SHIP_DATE Timestamp,
NEXT_SHIP_DATE Timestamp,
CONDITION_CODE Varchar(10),
QTY_ORDERED Double precision,
QTY_PENDING_INVOICE Double precision,
QTY_INVOICED Double precision,
UNIT_PRICE Double precision,
EXCHANGE_RATE Double precision,
UNIT_COST Double precision,
ITEM_NUMBER Integer,
CONSIGNMENT_CODE Char(10),
NOTES Blob sub_type 1,
STOCK_LINE Integer,
STM_AUTO_KEY Integer,
SERIAL_NUMBER Varchar(40),
REMARKS Varchar(50),
PN Varchar(40),
PNM_AUTO_KEY Integer,
GR_CODE Varchar(10),
CUSTOMER_PRICE Double precision,
OPEN_FLAG Char(1),
ROUTE_CODE Char(1),
ROUTE_DESC Varchar(20),
COMPANY_CODE Varchar(10),
SITE_CODE Varchar(10),
COMPANY_NAME Varchar(50),
COMPANY_REF_NUMBER Varchar(30),
CUST_REF Varchar(15),
HOT_PART Char(1)
)
AS
declare i integer;
BEGIN
i=0;
while ( i <= 2 ) do
BEGIN
for SELECT SOD_AUTO_KEY,CURRENCY_CODE,SO_CATEGORY_CODE, SO_NUMBER,INVC_NUMBER,ENTRY_DATE, SHIP_DATE, NEXT_SHIP_DATE, CONDITION_CODE, QTY_ORDERED,QTY_PENDING_INVOICE, QTY_INVOICED, UNIT_PRICE, EXCHANGE_RATE, UNIT_COST,ITEM_NUMBER, CONSIGNMENT_CODE, NOTES, STOCK_LINE, STM_AUTO_KEY, SERIAL_NUMBER,REMARKS, PN, PNM_AUTO_KEY, GR_CODE, CUSTOMER_PRICE, OPEN_FLAG, ROUTE_CODE,ROUTE_DESC, COMPANY_CODE, SITE_CODE, COMPANY_NAME, COMPANY_REF_NUMBER, CUST_REF, HOT_PART
FROM SPB_SALESHISTORY (i)
into :SOD_AUTO_KEY, :CURRENCY_CODE, :SO_CATEGORY_CODE, :SO_NUMBER, :INVC_NUMBER,
:ENTRY_DATE, :SHIP_DATE, :NEXT_SHIP_DATE, :CONDITION_CODE, :QTY_ORDERED,:QTY_PENDING_INVOICE,
:QTY_INVOICED, :UNIT_PRICE, :EXCHANGE_RATE, :UNIT_COST, :ITEM_NUMBER, :CONSIGNMENT_CODE, :NOTES, :STOCK_LINE,
:STM_AUTO_KEY, :SERIAL_NUMBER, :REMARKS, :PN, :PNM_AUTO_KEY, :GR_CODE, :CUSTOMER_PRICE, :OPEN_FLAG, :ROUTE_CODE,:ROUTE_DESC,
:COMPANY_CODE, :SITE_CODE, :COMPANY_NAME, :COMPANY_REF_NUMBER, :CUST_REF,:HOT_PART
DO
suspend;
i = i + 1;
end
END!!
SET TERM;!!
I ended up using IBEXPERT according to Ryno's response.
I often use 2 SQL comands into FlameRobin SQL editor:
output filename_to_export.txt;
select field1, field2 from tablename;
First you say command what file you whant the result of your query will be stored, second you say the query itself. Do not forget, they are two separated (distinct) commands, note the ; after each one. The order doesn't matter.
The output remains opened for append results if you perform more queries.

How can I use a parameter from a stored procedure in another procedure

I am created an online staff rota application. I have a stored procedure for each day of the week with an auto increment primary key for the Rota table. Each day within the selected week will have the same rota ID as a foreign key.
I have no problem with the first selected day but the following days return NULL for the foreign key RotaID as I don't know how to pass the RotaID into the other stored procedures to ensure the RotaID remains the same for the 7 days of the weekly Rota.
CREATE PROCEDURE [usp_RotaDay1]
#Week_Begin datetime,
#Week_End datetime,
#1ShiftDate datetime,
#1Day nchar (10),
AS
BEGIN
SET NOCOUNT ON;
DECLARE #RotaID int
IF NOT EXISTS
(
SELECT * FROM Rota
WHERE Week_Begin = #Week_Begin
AND
Week_End = #Week_End
)
BEGIN
INSERT INTO Rota
(
[Week_Begin],
[Week_End]
)
VALUES
(
#Week_Begin,
#Week_End
)
END
SELECT #RotaID = SCOPE_IDENTITY()
IF NOT EXISTS
(
SELECT * FROM DayShift
WHERE ShiftDate = #1ShiftDate
)
BEGIN
INSERT INTO DayShift
(
[RotaID],
[ShiftDate],
[Day]
)
VALUES
(
#RotaID,
#1ShiftDate,
#1Day
)
END
SET NOCOUNT OFF;
END
As you can see I have the RotaID declared in the Rota table and then passed as the foreign key in the DayShift table.
I would like to know if it is possible to pass this through to my other stored procedures which are similar to this one.
I'm not sure exactly what you are trying to do, but if you want to return the #RotaID parameter value to the calling program for use in a future procedure call, you can specify the parameter as OUTPUT:
CREATE PROCEDURE [usp_RotaDay1]
(
#Week_Begin datetime,
#Week_End datetime,
#1ShiftDate datetime,
#1Day nchar (10),
#RotaID int OUTPUT
)
AS
...
In each of your secondary stored procedures, you need to retrieve the primary key id using a select statement. You know weekbegin and weekend for all your secondary procedures right? so you know which row to pull to retrieve the id. Hope I made sense.

SQL Function not returning the same as normal query

I am using SQL Server 2008R2 and I have the following scripts.
select * from orderSummaryTotal(#orderid,#sessionid)
select
count(*) as Quantity,
IsNull(Sum(VatAmount),0) As VATAmount,
IsNull(Sum(NetAmount),0) As NetAmount,
IsNull(Sum(GrossAmount),0) as GrossAmount
from tbOrderProduct
where
Orderid = #orderid
and sessionid = #sessionid
When I run the Second Query it returns me values. Namely a Quantity of 3
However when I run the first Query it returns me a Quantity of 0.
The First Query is a Table Valued Function Here is the code.
ALTER FUNCTION [dbo].[OrderSummaryTotal](#orderid varchar, #sessionid uniqueidentifier)
RETURNS TABLE as
RETURN
select
count(*) as Quantity,
IsNull(Sum(VatAmount),0) As VATAmount,
IsNull(Sum(NetAmount),0) As NetAmount,
IsNull(Sum(GrossAmount),0) as GrossAmount
from tbOrderProduct
where
Orderid = #orderid
and sessionid = #sessionid
Both queries are identical but how come one returns a count of 3 and the other does not? Any ideas?
The reason is that you have varchar in your function definition with no length.
Try changing it to something like varchar(8000), or a number large enough to suit your needs.