is it possible in T SQL to use a function as a while parameter? I have the following code:
create function LoginExists (#p_login char(6))
returns varchar(5)
begin
if exists(select * from Student where student.slogin = #p_login)
return 'true'
return 'false'
end;
and
create procedure AddStudent2
(#p_fname varchar(30), #p_lname varchar(50), #p_tallness int)
as
declare #p_login char(6), #p_email varchar(50), #suffix char(3);
set #p_lname = LOWER(#p_lname);
set #suffix = '000';
begin
set #p_login = substring(#p_lname,1, 3) + #suffix;
while (LoginExists #p_login = 'true')
set #suffix = cast((CAST(#suffix as int) + 1) as char(3));
set #p_login = substring(#p_lname,1, 3) + #suffix;
set #p_email = #p_login + '#vsb.cz';
insert into Student values (#p_login, #p_fname, #p_lname, #p_email, #p_tallness);
end;
and when trying to compile it, an error occurs, saying: "Incorrect syntax near '#p_login'."
Your syntax for calling a function is in fact incorrect:
Replace:
while (LoginExists #p_login = 'true')
with:
while (dbo.LoginExists (#p_login)= 'true')
Replace
if exists(select * from Student where student.slogin = #p_login)
by
if exists(select * from Student where Student.slogin = #p_login)
Upper 'S' in student.slogin and i hope it work
Related
This trigger was not written by me or used with a stored proc original I modified it for my use. The problem to me appears to be one of permissions when the table is manually updated or inserted inSQL Server Management Studio the trigger works perfectly. When the Trigger is updated or inserted by a Stored Proc ran via an ODBC connection it does not modify the table and the Trigger does not work. If the trigger is disabled the stored Proc works as expected. So the error appers to be some form of permission error. Here is the trigger. (Using 2012)
Thanks In Advance
Donald S. Bossen
USE [JBI]
GO
/****** Object: Trigger [dbo].[send_ship_exec_info_to_p21] Script Date: 8/29/2018 3:22:26 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER TRIGGER [dbo].[send_ship_exec_info_to_p21] ON [dbo].[ship_exec]
FOR INSERT, UPDATE
AS
declare #pick_ticket_no varchar(50)
declare #tracking_no varchar(50)
declare #pickup_date varchar(50)
declare #carrier_id varchar(50)
declare #package_count varchar(50)
declare #delete_flag varchar(50)
declare #package_weight varchar(50)
declare #package_charge decimal(9,4)
declare #total_shipment_charge decimal(19,4)
declare #carrier_name varchar(50)
declare #customer_freight_charge decimal(9,4)
declare #saturday_delivery varchar(50)
declare #transaction_type varchar(50)
declare #billing_option varchar(3)
select
#pick_ticket_no = i.pick_ticket_no,
#tracking_no = i.tracking_no,
#pickup_date = i.pickup_date,--left(i.pickup_date,8),
#carrier_id = i.service_type,
#package_count = i.package_count,
#delete_flag = i.delete_flag,
#package_weight = i.package_weight,
#package_charge = i.package_charge,
#total_shipment_charge = i.total_shipping_and_handling_charge,
#saturday_delivery = i.saturday_delivery,
#transaction_type = i.transaction_type,
#billing_option = i.billing_option
from inserted i
if #transaction_type = 'Inv Return'
begin
declare #document_link_uid int
declare #document_link_area_uid int
declare #link_name varchar(255)
declare #link_path varchar(4099)
set #link_name = 'UPS shipment ' + cast(#pick_ticket_no as varchar(40)) + ': ' + #tracking_no
set #link_path = 'http://wwwapps.ups.com/WebTracking/processInputRequest?HTMLVersion=5.0&sort_by=status&term_warn=yes&tracknums_displayed=5&TypeOfInquiryNumber=T&loc=en_US&InquiryNumber1=' + #tracking_no + '&InquiryNumber2=&InquiryNumber3=&InquiryNumber4=&InquiryNumber5=&AgreeToTermsAndConditions=yes&track.x=28&track.y=2'
if #delete_flag = 'Y'
begin
update
PROPHET21.dbo.document_link
set
row_status_flag = '700'
,date_last_modified = getdate()
,last_maintained_by = 'Ship Exec Delete Flag'
where
key1_cd = 'return_number'
and key1_value = #pick_ticket_no
and link_path like '%' + #tracking_no + '%'
end
if #delete_flag = 'N'
begin
if not exists(select document_link_uid from PROPHET21.dbo.document_link where link_path like '%' + #tracking_no + '%')
begin
exec #document_link_uid = PROPHET21.dbo.p21_get_counter 'document_link', 1
INSERT INTO
PROPHET21.dbo.document_link
(
document_link_uid
,source_area_cd
,key1_cd
,key1_value
,link_name
,link_path
,row_status_flag
,date_created
,created_by
,date_last_modified
,last_maintained_by
,outside_use_flag
,mandatory_flag
)
VALUES
(
#document_link_uid
,1312
,'return_number'
,#pick_ticket_no
,#link_name
,#link_path
,704
,getdate()
,'SHIP EXEC'
,getdate()
,'SHIP EXEC'
,'N'
,'N'
)
exec #document_link_area_uid = PROPHET21.dbo.p21_get_counter 'document_link_area', 1
INSERT INTO
PROPHET21.dbo.document_link_area
(
document_link_area_uid
,document_link_uid
,display_area_cd
,row_status_flag
,date_created
,created_by
,date_last_modified
,last_maintained_by
)
VALUES
(
#document_link_area_uid
,#document_link_uid
,1312
,704
,getdate()
,'SHIP EXEC'
,getdate()
,'SHIP EXEC'
)
end
end
end
if #transaction_type <> 'SWS' or not exists(select oe_pick_ticket.pick_ticket_no from PROPHET21.dbo.oe_pick_ticket oe_pick_ticket where oe_pick_ticket.pick_ticket_no = #pick_ticket_no)
return
if #transaction_type = 'SWS' and exists(select oe_pick_ticket.pick_ticket_no from PROPHET21.dbo.oe_pick_ticket oe_pick_ticket where oe_pick_ticket.pick_ticket_no = #pick_ticket_no)
begin
if (#delete_flag = 'Y')
begin
declare #invoiced_already varchar (50)
select #invoiced_already = oe_pick_ticket.invoice_no
from PROPHET21.dbo.oe_pick_ticket oe_pick_ticket
where pick_ticket_no = #pick_ticket_no
if(#invoiced_already is null)
begin
update PROPHET21.dbo.clippership_return_10004
set delete_flag = 'Y'
where tracking_no = #tracking_no
update PROPHET21.dbo.oe_pick_ticket
set freight_out = 0, date_last_modified = getdate(), last_maintained_by = 'Ship Exec void package'
where pick_ticket_no = #pick_ticket_no
end
return
end
if (#delete_flag = 'N')--#tracking_no like '1z%' and
Begin
declare #customer_pays_outgoing_freight char(1)
select
#customer_pays_outgoing_freight = freight_code.outgoing_freight
from
PROPHET21.dbo.oe_pick_ticket oe_pick_ticket
inner join PROPHET21.dbo.freight_code freight_code on oe_pick_ticket.freight_code_uid = freight_code.freight_code_uid and oe_pick_ticket.company_id = freight_code.company_id
where
oe_pick_ticket.pick_ticket_no = #pick_ticket_no
select
#carrier_name = carrier.name
from
PROPHET21.dbo.address carrier
where
carrier.id = #carrier_id
select #customer_freight_charge =
cast(case
when #billing_option in ('REC', 'TP', 'CB') then 0
when coalesce(#customer_pays_outgoing_freight, 'Y') = 'N' then 0
else ((#total_shipment_charge) / #package_count)
end as decimal(19,2))
update PROPHET21.dbo.oe_pick_ticket
set freight_out = isnull(freight_out, 0) + isnull(#customer_freight_charge, 0),
carrier_id = #carrier_id,
tracking_no = #tracking_no
where pick_ticket_no = #pick_ticket_no
insert into PROPHET21.dbo.clippership_return_10004
(pick_ticket_no,
tracking_no,
package_weight,
order_count,
shipped_date,
carrier_name,
total_charge,
processed_flag,
delete_flag,
date_created,
date_last_modified,
last_maintained_by,
line_number)
values
(#pick_ticket_no,
#tracking_no,
#package_weight,
#package_count,
#pickup_date,
#carrier_name,
#customer_freight_charge,
'N',
'N',
getdate(),
getdate(),
'SHIP EXEC',
0)
end
return
End
UPDATE SampleTable
SET Schemaname = #SchemaName,
SchemaCode = #SchemaCode,
ForeignKeyColumn = #ForeignKeyColumn,
IsChildSchema = #IsChildSchema,
ModifiedBy = #ModifiedBy,
ModifiedDate = #ModifiedDate
WHERE
DataSchemaID = #DataSchemaId
My #ForeignKeyColumn parameter is
2233^SITE_CLM_NUMBER,2236^SITE_ID_N,
Can anyone help me in updating ForeignKeyColumn='SITE_CLM_NUMBER' where DataSchemaID=2233 and ForeignKeyColumn='SITE_ID_N' where DataSchemaID=2236
It's easy to pass multiple parameter values to a query, using a Table Valued Parameter. These are available in all versions of SQL Server since 2008.
First, you need to create a Table type with the fields you want:
CREATE TYPE dbo.KeyValueType AS TABLE
( Key int, Value nvarchar(50) )
This allows you to specify a parameter of type KeyValueType with the Key/Value combinations you want, eg #updatedColumns.
You can join the target table with the TVP to update rows with matching DataSchemaID values:
Create Procedure UpdateSchemas(...., #updatedColumns dbo.KeyValueType)
UPDATE SampleTable
SET
Schemaname=#SchemaName
,SchemaCode=#SchemaCode
,ForeignKeyColumn=t.Value
,IsChildSchema=#IsChildSchema
,ModifiedBy=#ModifiedBy
,ModifiedDate=#ModifiedDate
FROM SampleTable
INNER JOIN #updatedColumns t
ON t.ID=DataSchemaID
You can add an SplitString function, like this one :
How to Split String by Character into Separate Columns in SQL Server
CREATE FUNCTION [dbo].[Split]
(
#String varchar(max)
,#Delimiter char
)
RETURNS #Results table
(
Ordinal int
,StringValue varchar(max)
)
as
begin
set #String = isnull(#String,'')
set #Delimiter = isnull(#Delimiter,'')
declare
#TempString varchar(max) = #String
,#Ordinal int = 0
,#CharIndex int = 0
set #CharIndex = charindex(#Delimiter, #TempString)
while #CharIndex != 0 begin
set #Ordinal += 1
insert #Results values
(
#Ordinal
,substring(#TempString, 0, #CharIndex)
)
set #TempString = substring(#TempString, #CharIndex + 1, len(#TempString) - #CharIndex)
set #CharIndex = charindex(#Delimiter, #TempString)
end
if #TempString != '' begin
set #Ordinal += 1
insert #Results values
(
#Ordinal
,#TempString
)
end
return
end
Now you can easily extract each part of your input parameter.
declare #I int;
declare #TMP nvarchar(255);
set #I = 1;
set #TMP = null;
set #TMP = (select StringValue from Split(#ForeignKeyCoumn, ',') where Ordinal = 1);
while #TMP <> null
begin
set #ForeignKeyColumn = (select StringValue from Split(#TMP, '^') where Ordinal = 1);
set #DataSchemaID = (select StringValue from Split(#TMP, '^') where Ordinal = 2);
-- Update here your table with #ForeignKeyColumn and #DataSchemaID values
set #I = #I + 1;
set #TMP = null;
set #TMP = (select StringValue from Split(#ForeignKeyCoumn, ',') where Ordinal = #I);
end
PS: If your are using SQL Server 2016 it already includes an SplitString function, so you won't need to add your own. https://learn.microsoft.com/en-us/sql/t-sql/functions/string-split-transact-sql
I have the following code:
CREATE FUNCTION db_owner.GetComp
(
#CompID bigint,
#ComponentType nvarchar(50)
)
RETURNS TABLE
AS
RETURN /* SELECT ... FROM ... */
IF (#ComponentType = 'WMCOMP') begin
RETURN
SELECT *
FROM WMCOMP
WHERE wmcompid = #CompID
end
ELSE IF (#ComponentType = 'ADECOMP') begin
RETURN
SELECT *
FROM ADECOMP
WHERE adecompid = #CompID
end
When trying to save it in Visual Studio, the following error is displayed:
Incorrect syntax near IF
I simply cannot see what is wrong. Any help will be appreciated.
Try this one -
CREATE FUNCTION db_owner.GetComp
(
#CompID bigint
, #ComponentType nvarchar(50)
)
RETURNS #Result TABLE (col1 INT, ...)
AS
BEGIN
INSERT INTO #Result (col1, ...)
SELECT *
FROM (
SELECT *
FROM dbo.WMCOMP
WHERE wmcompid = #CompID
AND #ComponentType = 'WMCOMP'
UNION ALL
SELECT *
FROM dbo.ADECOMP
WHERE adecompid = #CompID
AND #ComponentType = 'ADECOMP'
) f
RETURN
END
You have a missing comma in param list:
CREATE FUNCTION db_owner.GetComp
(
#CompID bigint, --<--- need a comma here
#ComponentType nvarchar(50)
)
I created the following function in SQL 2008
CREATE FUNCTION dbo.udfSetSupplyStatus(#strOrderID nvarchar(16), #intLineNo int, #intOrderQty int, #strPartID nvarchar(16), #strWarehouseID nvarchar(16), #dtAsOfDate datetime, #strCalcMode nvarchar(16))
RETURNS nvarchar(32)
AS
BEGIN
DECLARE #strReturnValue nvarchar(32), #intQtyOnHand int, #intQtyOnOrder int, #intQtyPlanned int, #dtWantDate datetime
IF (#strCalcMode = 'S')
BEGIN
SELECT
#intQtyOnHand = (pw.available_qty + pw.committed_co + pw.committed_req + pw.committed_ibt + pw.locked_qty),
#intQtyOnOrder = (pw.expected_po + pw.expected_wo)
FROM VE_PART_WAREHOUSE as pw
INNER JOIN VE_PART as p on pw.part_id = p.id
WHERE pw.part_id = #strPartID
and pw.warehouse_id = #strWarehouseID
END
BEGIN
select
#dtWantDate = WANT_DATE,
#intQtyPlanned = ORDER_QTY
from VE_PLANNED_ORDER
where PART_ID = #strPartID
AND WAREHOUSE_ID = #strWarehouseID
END
IF(#intQtyOnHand >= #intOrderQty)
SET #strReturnValue = 'InStock'
ELSE IF(#intQtyOnHand + #intQtyPlanned) >= #intOrderQty
SET #strReturnValue = 'Expected'
ELSE
SET #strReturnValue = 'NoSupply'
RETURN #strReturnValue
END
I can see the function in the Scalar-valued Functions under Programmability in the Database I'm using but when I try to call the function Intellisense doesn't detect my function.
I having problems with this function, seems like #idUsuario and #passCorrecto aren't getting any value, so, when I use this variables in the where clause I'm not getting any result data.
ALTER FUNCTION [dbo].[login](#usuario varchar(20), #password varchar(20))
RETURNS #info TABLE (nombre varchar(70) not null, tipo varchar(30) not null)
AS
BEGIN
DECLARE #idUsuario int = dbo.usuarioExiste(#usuario)
DECLARE #passCorrecto bit = dbo.passwordCorrecto(#idUsuario, #password)
INSERT #info
SELECT
usuarios.nombreUsuario, tiposUsuarios.tipoUsuario
FROM
usuarios
LEFT JOIN
tiposUsuarios
ON
usuarios.idTipoUsuario = tiposUsuarios.idTipoUsuario
WHERE
usuarios.idUsuario = #idUsuario and
usuarios.estatus = 'ACTIVO' and
#passCorrecto = 1
RETURN
END
What am I doing wrong?
EDIT
Here are the function used above:
ALTER FUNCTION [dbo].[usuarioExiste]
(
#usuario varchar(20)
)
RETURNS integer
AS
BEGIN
DECLARE #idUsuario integer
SELECT
#idUsuario = idUsuario
FROM
usuarios
WHERE
usuario = #usuario
if #idUsuario is null begin
set #idUsuario = 0
end
RETURN #idUsuario
END
ALTER FUNCTION [dbo].[passwordCorrecto]
(
#usuario varchar(20),
#password varchar(20)
)
RETURNS bit
AS
BEGIN
DECLARE #esCorrecto bit
SELECT
#esCorrecto = case when password = #password then 1 else 0 end
FROM
usuarios
WHERE
usuario = #usuario
RETURN #esCorrecto
END
EDIT 2
As suggested by Beth, I created new functions that returns the values that I need like this:
CREATE FUNCTION [dbo].[usuarioExisteTest]
(
#usuario varchar(20)
)
RETURNS int
AS
BEGIN
declare #idUsuario int;
set #idUsuario = 1;
return (#idUsuario);
END;
By doing this I'm getting the data I need, am I setting the values to return the wrong way in the original functions?
DECLARE #idUsuario integer
SELECT
#idUsuario = idUsuario
FROM
usuarios
WHERE
usuario = #usuario
I know SQL Server 2008 supports the combined DECLARE/assign, but have you tried separating them?
DECLARE #idUsuario int
SET idUsuario = dbo.usuarioExiste(#usuario)
DECLARE #passCorrecto bit
SET passCorrecto = dbo.passwordCorrecto(#idUsuario, #password)
From BOL
Assigns a value to the variable
in-line. The value can be a constant
or an expression, but it must either
match the variable declaration type or
be implicitly convertible to that
type.
Of course, a udf is an expression, but is it possible there is some anomaly when used in DECLARE (like when you use a udf in CHECK constraint: it's not reliable). Or DECLARE ins a udf for some reason.
Please humour me. Try it.
Also, you have no "failsafe" inside dbo.passwordCorrecto which means it could return NULL which will always evaluate to false in the outer udf.
try printing the values of the variables after you declare them. If they aren't set correctly, try calling the functions in a new query window instead of within [dbo].[login]. That should help identify the problem.
I've found a solution, seem like using select #var = some_value doesn't work well. See this:
A SELECT statement that contains a variable assignment cannot be used to also perform typical result set retrieval operations.
These are the fixed functions:
usuarioExiste
CREATE FUNCTION [dbo].[usuarioExiste]
(
#usuario varchar(20)
)
RETURNS int
AS
BEGIN
declare #idUsuario int = 0;
set #idUsuario = (
select
idUsuario
from
usuarios
where
usuario = #usuario);
if #idUsuario is null begin
set #idUsuario = 0;
end;
return (#idUsuario);
END;
passwordCorrecto
CREATE FUNCTION [dbo].[passwordCorrecto]
(
#idUsuario int,
#password varchar(20)
)
RETURNS bit
AS
BEGIN
declare #esCorrecto bit = 'false';
set #esCorrecto = (
select
case when password = #password then 'true' else 'false' end
from
usuarios
where
usuarios.idUsuario = #idUsuario);
return (#esCorrecto);
END;
and login
CREATE FUNCTION [dbo].[login](#usuario varchar(20), #password varchar(20))
RETURNS #info TABLE (nombre varchar(70) not null, tipo varchar(30) not null)
AS
BEGIN
DECLARE #idUsuario int = dbo.usuarioExistetest(#usuario);
DECLARE #passCorrecto bit = dbo.passwordCorrectotest(#idUsuario, #password);
INSERT #info
SELECT
usuarios.nombreUsuario, tiposUsuarios.tipoUsuario
FROM
usuarios
LEFT JOIN
tiposUsuarios
ON
usuarios.idTipoUsuario = tiposUsuarios.idTipoUsuario
WHERE
usuarios.idUsuario = #idUsuario and
usuarios.estatus = 'ACTIVO' and
#passCorrecto = 'true';
RETURN
END;