Why is my SAP B1 stored procedure not working for UDF - sapb1

I created a UDF RetReas (Return Reason) for Sales AR > Return. The UDF is applied to the rows. I need to block the adding of drafts if the UDF is blank. My code on the stored procedure, SBO_SP_TransactionNotification is not working. The draft for Return is still being added even if the UDF is blank. Here is the code
IF (#object_type ='112' AND #transaction_type IN ('A','U'))
BEGIN
DECLARE #RetReason nvarchar(30)
SELECT #LineNum = b.VisOrder+1, #ObjType = CAST(A.ObjType as varchar(32)), #RetReason = COALESCE(B.U_RetReas,'')
FROM ODRF A INNER JOIN DRF1 B ON A.DocEntry = B.DocEntry
WHERE A.DocEntry = #list_of_cols_val_tab_del and ISNULL(A.WddStatus,'-') <> '-'
IF (#ObjType = '16')
IF ( #RetReason = '')
BEGIN
SET #error = -100018
SET #error_message=N'Return reason is required!'
END
END

when i remove this it is working on my local
and ISNULL(A.WddStatus,'-') <> '-'
is this document related to an Authorization Process?

Related

How to get rid of Cursor and use UPDATE with SELECT

I believe that the cursor used in this code is the reason for some major performance issues, however I am new to TSQL.
Following script runs on SQL SERVER 2008. I am trying to redo it so I use JOIN statements instead, however I have not been able to do so successfully.
DECLARE AIRAMSDET CURSOR FOR
SELECT BILL, RECIEPT, NAME
FROM Client_Table
WHERE IsProcessed = 1
AND TYPE IN ('Sub','First_Time','Old') AND LEN(BILL) > 1
OPEN AIRAMSDET
FETCH AIRAMSDET into #VARBILL, #VARRECIEPT, #VARNAME
WHILE ##Fetch_Status = 0
BEGIN
UPDATE archieve
SET entry = left(#VARBILL + '- '+ #VARNAME)
WHERE archiveID = #VARBILL
END
It should be something like following
UPDATE ARCHIEVE
SET ENTRY = CT.BILL + '-' + CT.NAME
FROM CLIENT_TABLE CT
WHERE
ARCHIEVE.ARCHIVEID = CT.BILL
AND CT.ISPROCESSED = 1
AND CT.TYPE IN ('Sub','First_Time','Old') AND LEN(BILL) > 1
I have not included LEFT() as its use in your query wasn't very clear. Left takes an integer_expression as its second parameter while you are passing ##VARNAME which most likely is a VARCHAR. Please add that as you deem fit.

opening a cursor after some code

I have some Stored Procedure in DB2. Some lines of code (INSERT, UPDATE etc). After some operations I have IF condition that opening/not opening CURSOR. For some reason the CURSOR is not opened even if IF condition is TRUE. All the code before the CURSOR works fine. If I'll remove it, so the CURSOR will works fine. If I'll put the CURSOR in separate SP, it works fine (calling for another SP from this SP). But together for some reason it not works. I can't understand why. I need this code for the IF condition.
That's how it looks (only 1 row with INSERT left outside the CURSOR):
DECLARE C1 CURSOR WITH HOLD FOR
SELECT s.KEY, s.CODE, s.PRODUCT, s.AMOUNT
FROM DB2ADMIN.SALES s, DB2ADMIN.PRODUCTS p
WHERE s.DATE_KEY = CDC AND s.PRODUCT_KEY = p.PRODUCT_KEY;
DECLARE CONTINUE HANDLER FOR NOT FOUND
SET EOF = 1;
INSERT INTO DB2ADMIN.IA_BASE_SALES_TMP (SOME_FIELD) VALUES (SOME_VALUE);
IF true THEN
OPEN C1;
WHILE EOF = 0 DO
FETCH FROM C1 INTO SP_KEY, SP_CODE, SP_KEY, SP_PRODUCT, SP_AMOUNT;
MERGE INTO DB2ADMIN.IA_BASE_SALES_TMP t
USING (
SELECT POS, p.KEY, s.TELLER, s.TYPE, s.AMOUNT, s.CDC
FROM DB2ADMIN.COMMISSIONS s, DB2ADMIN.PRODUCTS p
WHERE TELLER = SP_TELLER AND TYPE = SP_TYPE
) e ON t.TELLER_KEY = e.TELLER_ID
WHEN matched
THEN UPDATE SET t.KEY = e.KEY, t.UPD = 0;
END WHILE;
CLOSE C1;
END IF;
Thanks to Jean.
Replacing the cursor with FOR loop and everything works OK.

SQL function not working properly, but does when not as a function

I'm having another issue with a SQL Function that I had written. If I run it not in a function and use declared variables, then it works perfectly. But as soon as I put it into a function and run it, nothing appears, its empty.
I cannot put this into a stored procedure, it needs to be in a function.
the code is
select * from [MYTABLE]
where MajorGroupID = #MajorGroupID
and ((#Status = 0 and (
Inactive = 0)
))
or MajorGroupID = #MajorGroupID and (#Status = 1 and (Inactive = 0 or Inactive = 1))
I am not really familiar with functions, I can do basic things with functions but when it comes to adding logic to it. If I was allowed to use stored procedures then I wouldn't be having problems.
This is MSSQL and using SQL Server 2010.
EDIT, Added complete function
CREATE FUNCTION [dbo].[WT_FN_GET_MYTABLE_By_MajorGroupID_Inactive]
(
#MajorGroupID varchar,
#Status int
)
RETURNS TABLE
AS
RETURN
select * from [MYTABLE]
where MajorGroupID = #MajorGroupID
and ((#Status = 0 and (
Inactive = 0)
))
or MajorGroupID = #MajorGroupID and (#Status = 1 and (Inactive = 0 or Inactive = 1))
You don't provide a length for #MajorGroupID varchar, so it is going to be 1 by default, at which point it will not find anything in the table.
Provide a length, e.g. #MajorGroupID varchar(30).

conditional handling of update sql script depending on input parameter

I am new to SQL and using Oracle 11. I need to write a sql script which uses different update command based on whether the input param is null or not null.
I need something like this
['&' followed by the parameter name is the way i see parameters being used in other such
script for our project]
IF &PRG_ID IS NULL
UPDATE PROGRAM_TABLE P SET HANDLED_IND = 'Y' WHERE EXISTS
(SELECT 1 FROM HANDLED_PROGRAM H WHERE H.PROGRAM_ID = P.PROGRAM_ID);
ELSE
UPDATE PROGRAM_TABLE P SET HANDLED_IND = 'Y' WHERE
P.PROGRAM_ID = &PRG_ID AND EXISTS
(SELECT 1 FROM HANDLED_PROGRAM H WHERE H.PROGRAM_ID = P.PROGRAM_ID);
END IF;
Something like (is not tested):
UPDATE PROGRAM_TABLE P SET HANDLED_IND = 'Y' WHERE EXISTS
(SELECT 1 FROM HANDLED_PROGRAM H WHERE H.PROGRAM_ID = P.PROGRAM_ID)
AND (&PRG_ID IS NULL OR P.PROGRAM_ID = &PRG_ID);
But take into account this change may lead to the performance degradation for the case when PRG_ID has definite value.

Stored procedure to find next and previous row in SQL Server 2005

Right now I have this code to find next and previous rows using SQL Server 2005. intID is the gallery id number using bigint data type:
SQL = "SELECT TOP 1 max(p.galleryID) as previousrec, min(n.galleryID) AS nextrec FROM gallery AS p CROSS JOIN gallery AS n where p.galleryid < '"&intID&"' and n.galleryid > '"&intID&"'"
Set rsRec = Server.CreateObject("ADODB.Recordset")
rsRec.Open sql, Conn
strNext = rsRec("nextrec")
strPrevious = rsRec("previousrec")
rsRec.close
set rsRec = nothing
Problem Number 1:
The newest row will return nulls on the 'next record' because there is none. The oldest row will return nulls because there isn't a 'previous record'. So if either the 'next record' or 'previous record' doesn't exist then it returns nulls for both.
Problem Number 2:
I want to create a stored procedure to call from the DB so intid can just be passed to it
TIA
This will yield NULL for previous on the first row, and NULL for next on the last row. Though your ordering seems backwards to me; why is "next" lower than "previous"?
CREATE PROCEDURE dbo.GetGalleryBookends
#GalleryID INT
AS
BEGIN
SET NOCOUNT ON;
;WITH n AS
(
SELECT galleryID, rn = ROW_NUMBER()
OVER (ORDER BY galleryID)
FROM dbo.gallery
)
SELECT
previousrec = MAX(nA.galleryID),
nextrec = MIN(nB.galleryID)
FROM n
LEFT OUTER JOIN n AS nA
ON nA.rn = n.rn - 1
LEFT OUTER JOIN n AS nB
ON nB.rn = n.rn + 1
WHERE n.galleryID = #galleryID;
END
GO
Also, it doesn't make sense to want an empty string instead of NULL. Your ASP code can deal with NULL values just fine, otherwise you'd have to convert the resulting integers to strings every time. If you really want this you can say:
previousrec = COALESCE(CONVERT(VARCHAR(12), MIN(nA.galleryID)), ''),
nextrec = COALESCE(CONVERT(VARCHAR(12), MAX(nB.galleryID)), '')
But this will no longer work well when you move from ASP to ASP.NET because types are much more explicit. Much better to just have the application code be able to deal with, instead of being afraid of, NULL values.
This seems like a lot of work to get the previous and next ID, without retrieving any information about the current ID. Are you implementing paging? If so I highly recommend reviewing this article and this follow-up conversation.
Try this (nb not tested)
SELECT TOP 1 max(p.galleryID) as previousrec, min(n.galleryID) AS nextrec
FROM gallery AS p
CROSS JOIN gallery AS n
where (p.galleryid < #intID or p.galleryid is null)
and (n.galleryid > #intID or n.galleryid is null)
I'm assuming you validate that intID is an integer before using this code.
As for a stored procedure -- are you asking how to write a stored procedure? If so there are many tutorials which are quite good on the web.
Since Hogan contributed with the SQL statement, let me contribute with the stored proc part:
CREATE PROCEDURE spGetNextAndPreviousRecords
-- Add the parameters for the stored procedure here
#intID int
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
SELECT TOP 1 max(p.galleryID) as previousrec, min(n.galleryID) AS nextrec
FROM gallery AS p
CROSS JOIN gallery AS n
where (p.galleryid < #intID or p.galleryid is null)
and (n.galleryid > #intID or n.galleryid is null)
END
And you call this from code as follows (assuming VB.NET):
Using c As New SqlConnection(ConfigurationManager.ConnectionStrings("ConnectionString").ConnectionString)
c.Open()
Dim command = New SqlCommand("spGetNextAndPreviousRecords")
command.Parameters.AddWithValue("#intID", yourID)
Dim reader as SqlDataReader = command.ExecuteReader()
While(reader.Read())
' read the result here
End While
End Using