Let's say I have 2 counties:
A
B
Each has it's own URL:
www.A.com
www.B.com
I have a stored procedure that accepts 3 variables to enable or disable the service to the URL. The #Enable variable is required but the user can enter the #County_Code or #WebserviceURL variables - or both. But if they enter both, I want to verify that the record exits in the database.
For example,
EXEC [dbo].usp_webservice_change_status
#enable = 1,
#county_code = 'A',
#webserviceURL = 'www.A.com';
should execute and update the Enable flag.
But if I execute with the following values, I would like to have an error returned stating something to the effect that County A does not have a corresponding value of www.B.com.
EXEC [dbo].usp_webservice_change_status
#enable = 1,
#county_code = 'A',
#webserviceURL = 'www.B.com';
Here is the complete stored procedure:
ALTER PROCEDURE [dbo].[usp_webservice_change_status]
#enable AS BIT,
#county_code AS CHAR(2) = NULL,
#webserviceURL AS VARCHAR(4000) = NULL
AS
BEGIN
SET NOCOUNT ON;
IF #enable IS NULL
RAISERROR ('The value for #enable should not be null', 15, 1);
IF ( #county_code IS NULL AND #webserviceURL IS NULL )
RAISERROR ('The value for #county_code and #webserviceURL cannot both be null', 15, 1);
IF ( #county_code IS NOT NULL AND #webserviceURL IS NULL )
UPDATE dbo.webservice_config
SET [enable] = #enable,
comments = CASE
WHEN #enable = 1 THEN 'Enabled by ' + SUSER_SNAME()
ELSE 'Disabled by ' + SUSER_SNAME()
END
WHERE county_code = #county_code
ELSE IF (#county_code IS NULL AND #webserviceURL IS NOT NULL )
UPDATE dbo.webservice_config
SET [enable] = #enable,
comments = CASE
WHEN #enable = 1 THEN 'Enabled by ' + SUSER_SNAME()
ELSE 'Disabled by ' + SUSER_SNAME()
END
WHERE webservice_URL = #webserviceURL
ELSE IF ( #county_code IS NOT NULL AND #webserviceURL IS NOT NULL )
UPDATE dbo.webservice_config
SET [enable] = #enable,
comments = CASE
WHEN #enable = 1 THEN 'Enabled by ' + SUSER_SNAME()
ELSE 'Disabled by ' + SUSER_SNAME()
END
WHERE ( county_code = #county_code AND webservice_URL = #webserviceURL )
END;
You could do this with another IF statement if I understand what you want correctly... just add these two lines at the bottom of your PROCEDURE just before your END;
IF(##ROWCOUNT) < 1
RAISERROR('Nothing Updated Due to Non Matching Records',15,1)
So it will look like this
--all your other code
WHERE ( county_code = #county_code AND webservice_URL = #webserviceURL )
IF(##ROWCOUNT) < 1
RAISERROR('Nothing Updated Due to Non Matching Records',15,1)
END;
You could also wrap the entire thing in another IF if you want
ELSE IF ( #county_code IS NOT NULL AND #webserviceURL IS NOT NULL )
IF(SELECT 1 FROM dbo.webservice_config WHERE county_code = #county_code AND webservice_URL = #webserviceURL) < 1
RAISERROR('Nothing Updated Due to Non Matching Records',15,1)
ELSE
UPDATE dbo.webservice_config
SET [enable] = #enable,
comments = CASE
WHEN #enable = 1 THEN 'Enabled by ' + SUSER_SNAME()
ELSE 'Disabled by ' + SUSER_SNAME()
END
WHERE ( county_code = #county_code AND webservice_URL = #webserviceURL )
END;
You could also use EXISTS and other syntax instead of what I used... just some examples.
Related
I used this function to extract decimal numbers from a string:
ALTER Function [dbo].[udf_ExtractNumber] (#String nvarchar(256))
RETURNS nvarchar(max)
AS
BEGIN
DECLARE #AlphaNumeric varchar(256)
,#Res varchar(256)
SET #AlphaNumeric = #String
SET #Res = NULL
WHILE (PATINDEX('%[0-9]%', #AlphaNumeric) > 0 )
BEGIN
IF (PATINDEX('%[0-9]%', #AlphaNumeric) >0 AND PATINDEX('%[0-9]%', #AlphaNumeric) < CHARINDEX(',', #AlphaNumeric))
BEGIN
SET #Res = CONCAT(#Res ,SUBSTRING(#AlphaNumeric, PATINDEX('%[0-9]%', #AlphaNumeric), 1) )
SET #AlphaNumeric = RIGHT(#AlphaNumeric,len(#AlphaNumeric)- PATINDEX('%[0-9]%', #AlphaNumeric))
END
ELSE IF (CHARINDEX(',', #AlphaNumeric) >0 AND CHARINDEX(',', #AlphaNumeric) < PATINDEX('%[0-9]%', #AlphaNumeric))
BEGIN
SET #Res = CONCAT(#Res ,SUBSTRING(#AlphaNumeric, CHARINDEX(',', #AlphaNumeric), 1) )
SET #AlphaNumeric = RIGHT(#AlphaNumeric,len(#AlphaNumeric)- CHARINDEX(',', #AlphaNumeric))
END
ELSE IF (PATINDEX('%[0-9]%', #AlphaNumeric) >0)
BEGIN
SET #Res = CONCAT(#Res, SUBSTRING(#AlphaNumeric, PATINDEX('%[0-9]%', #AlphaNumeric), 1) )
SET #AlphaNumeric = RIGHT(#AlphaNumeric,len(#AlphaNumeric)- PATINDEX('%[0-9]%', #AlphaNumeric))
END
ELSE IF (CHARINDEX(',', #AlphaNumeric) >0 )
BEGIN
SET #Res = CONCAT(#Res,SUBSTRING(#AlphaNumeric, CHARINDEX(',', #AlphaNumeric), 1))
SET #AlphaNumeric = RIGHT(#AlphaNumeric,len(#AlphaNumeric)- CHARINDEX(',', #AlphaNumeric))
END
END
Return #Res
This is working fine, output is exactly what i want.
It converts for example "adsfadf 18,12 adfasdsfa" to 18,12
However, when I want to work with the number I cannot convert it to a float.
Dividing or multiplying it gives the following error:
Conversion failed when converting the nvarchar value '7,5' to data type int.
Based on comments of Ali Fidenli, I adjust the last part of the code to get it working. Thanks
END
Return replace(#Res,',','.')
I am new to plpgsql and I am now close to what I want to do :
create or replace function shop_apply_search_filters(
price_min integer default null,
price_max integer default null,
ecom_id integer default null,
cat_1 text default null,
cat_2 text default null)
returns text as
$$
BEGIN
IF cat_1 = '' THEN
cat_1 = null;
END IF;
IF cat_2 = '' THEN
cat_2 = null;
END IF;
select concat_ws(
' and ',
'price < ' || price_min,
'price > ' || price_max,
'ecom_id = ' || ecom_id,
'category_1 = ' || cat_1,
'category_2 = ' || cat_2
) AS filters;
END;
$$
LANGUAGE PLPGSQL;
If I call it SELECT shop_apply_search_filters(10,null,null,'',''),I have this error :
ERROR: query has no destination for result data
HINT: If you want to discard the results of a SELECT, use PERFORM instead.
CONTEXT: PL/pgSQL function shop_apply_search_filters(integer,integer,integer,text,text) line 11 at SQL statement
SQL state: 42601
I am not sure what I need to change to make it work
You need to return the result
RETURN
concat_ws(
' and ',
'price < ' || price_min,
'price > ' || price_max,
'ecom_id = ' || ecom_id,
'category_1 = ' || cat_1,
'category_2 = ' || cat_2
);
i'm trying to generate dynamic query to insert results of dynamic select into table. my code is the following.
CREATE OR REPLACE FUNCTION public.report_get_result(
datekey integer)
RETURNS setof public.logic_result_rcd
LANGUAGE 'plpgsql'
COST 100
VOLATILE
AS $BODY$
DECLARE
LogicID text;
SheetName text;
Row_ID text;
Column_ID text;
FromTable text;
Operation text;
Amount text;
CriteriaType_1 text;
Function_1 text;
Criteria_1 text;
CriteriaType_2 text;
Function_2 text;
Criteria_2 text;
CriteriaType_3 text;
Function_3 text;
Criteria_3 text;
sql text;
INC Integer;
begin
DROP TABLE IF EXISTS loans;
create temp table loans as
select * from loan.vfact_state_principal where "DateKey" = datekey;
DECLARE cursor_logic REFCURSOR;
BEGIN
OPEN cursor_logic for SELECT "LogicID" FROM logic_table_rcd;
LOOP
FETCH cursor_logic INTO INC;
if not found then exit;
end if;
BEGIN
select into LogicID "LogicID" from public.logic_table_rcd WHERE
"LogicID" = 1;
select into SheetName "SheetName" from public.logic_table_rcd WHERE
"LogicID" = 1;
select into Row_ID "Row_ID" from public.logic_table_rcd WHERE "LogicID"
= 1;
select into Column_ID "Column_ID" from public.logic_table_rcd WHERE
"LogicID" = 1;
select into FromTable "FromTable" from public.logic_table_rcd WHERE
"LogicID" = 1;
select into Operation "Operation" from public.logic_table_rcd WHERE
"LogicID" = 1;
select into Amount "Amount" from public.logic_table_rcd WHERE "LogicID"
= 1;
select into CriteriaType_1 CASE WHEN "CriteriaType_1" <> '' OR
"CriteriaType_1" is not null THEN (' WHERE "' || "CriteriaType_1" || '"')
ELSE '' END from public.logic_table_rcd WHERE "LogicID" = 1;
select into Function_1 CASE WHEN "Function_1" is null THEN '' ELSE
"Function_1" END from public.logic_table_rcd WHERE "LogicID" = 1;
select into Criteria_1 CASE WHEN "Criteria_1" is null THEN '' ELSE
"Criteria_1" END from public.logic_table_rcd WHERE "LogicID" = 1;
select into CriteriaType_2 CASE WHEN "CriteriaType_2" <> '' OR
"CriteriaType_2" is not null THEN ' AND "' || "CriteriaType_2" || '"' ELSE
'' END from public.logic_table_rcd WHERE "LogicID" = 1;
select into Function_2 CASE WHEN "Function_2" is null THEN '' ELSE
"Function_2" END from public.logic_table_rcd WHERE "LogicID" = 1;
select into Criteria_2 CASE WHEN "Criteria_2" is null THEN '' ELSE
"Criteria_2" END from public.logic_table_rcd WHERE "LogicID" = 1;
select into CriteriaType_3 CASE WHEN "CriteriaType_3" <> '' or
"CriteriaType_3" is not null THEN ' AND "' || "CriteriaType_3" || '"' ELSE
'' END from public.logic_table_rcd WHERE "LogicID" = 1;
select into Function_3 CASE WHEN "Function_3" is null THEN '' ELSE
"Function_3" END from public.logic_table_rcd WHERE "LogicID" = 1;
select into Criteria_3 CASE WHEN "Criteria_3" is null THEN '' ELSE
"Criteria_3" END from public.logic_table_rcd WHERE "LogicID" = 1;
sql:= 'INSERT INTO public.logic_result_rc SELECT ' || INC::text || ', 1, '
|| DateKey::text || ', ''' || 'RCD' || ''', ''' || SheetName::text || ''', '
|| Row_ID::text || ', '
|| Column_ID::text || ', ' || Operation || '("' || Amount || '")' || ' FROM
' || FromTable
|| CriteriaType_1 || ' ' || Function_1 || ' ' || Criteria_1
|| CriteriaType_2 || ' ' || Function_2 || ' ' || Criteria_2
|| CriteriaType_3 || ' ' || Function_3 || ' ' || Criteria_3;
RETURN QUERY EXECUTE sql;
END;
END LOOP;
CLOSE cursor_logic;
END;
END;
$BODY$;
ALTER FUNCTION public.report_get_result(integer)
OWNER TO postgres;
But after execution I get the next error:
cannot open INSERT query as cursor
All variables are assigned correctly. may be insert must be somewhere else outside cursor? does INSERT INTO .... FETCH ALL statement exist?
INSERT by default doesn't return any rows, so there is nothing to fetch. You can fix this by appending your sql string with RETURNING *, with should return contents inserted into public.logic_result_rc.
So it would like this: RETURN QUERY EXECUTE concat(sql, ' RETURNING *');
Basic syntax is:
INSERT INTO table_name ( column_name [, ...] )
VALUES ( ) | query
RETURNING * --or list of columns, same syntax like for SELECT
DECLARE #SchemaName VARCHAR(100)
DECLARE #TableName VARCHAR(256)
DECLARE #IndexName VARCHAR(256)
DECLARE #ColumnName VARCHAR(100)
DECLARE #is_unique VARCHAR(100)
DECLARE #IndexTypeDesc VARCHAR(100)
DECLARE #FileGroupName VARCHAR(100)
DECLARE #is_disabled VARCHAR(100)
DECLARE #IndexOptions VARCHAR(MAX)
DECLARE #IndexColumnId INT
DECLARE #IsDescendingKey INT
DECLARE #IsIncludedColumn INT
DECLARE #TSQLScripCreationIndex VARCHAR(MAX)
DECLARE #TSQLScripDisableIndex VARCHAR(MAX)
DECLARE CursorIndex CURSOR
FOR
SELECT SCHEMA_NAME(t.schema_id) [schema_name] ,
t.name ,
ix.name ,
CASE WHEN ix.is_unique = 1 THEN 'UNIQUE '
ELSE ''
END ,
ix.type_desc ,
CASE WHEN ix.is_padded = 1 THEN 'PAD_INDEX = ON, '
ELSE 'PAD_INDEX = OFF, '
END
+ CASE WHEN ix.allow_page_locks = 1 THEN 'ALLOW_PAGE_LOCKS = ON, '
ELSE 'ALLOW_PAGE_LOCKS = OFF, '
END
+ CASE WHEN ix.allow_row_locks = 1 THEN 'ALLOW_ROW_LOCKS = ON, '
ELSE 'ALLOW_ROW_LOCKS = OFF, '
END
+ CASE WHEN INDEXPROPERTY(t.object_id, ix.name, 'IsStatistics') = 1
THEN 'STATISTICS_NORECOMPUTE = ON, '
ELSE 'STATISTICS_NORECOMPUTE = OFF, '
END
+ CASE WHEN ix.ignore_dup_key = 1 THEN 'IGNORE_DUP_KEY = ON, '
ELSE 'IGNORE_DUP_KEY = OFF, '
END + 'SORT_IN_TEMPDB = OFF,DROP_EXISTING = ON' AS IndexOptions ,
ix.is_disabled ,
FILEGROUP_NAME(ix.data_space_id) FileGroupName
FROM sys.tables t
INNER JOIN sys.indexes ix ON t.object_id = ix.object_id
WHERE ix.type > 0
AND ix.is_primary_key = 0
AND ix.is_unique_constraint = 0 --and schema_name(tb.schema_id)= #SchemaName and tb.name=#TableName
AND t.is_ms_shipped = 0
AND t.name <> 'sysdiagrams'
AND t.name = 'LegalEntity'
ORDER BY SCHEMA_NAME(t.schema_id) ,
t.name ,
ix.name
OPEN CursorIndex
FETCH NEXT FROM CursorIndex INTO #SchemaName, #TableName, #IndexName,
#is_unique, #IndexTypeDesc, #IndexOptions, #is_disabled, #FileGroupName
WHILE ( ##fetch_status = 0 )
BEGIN
DECLARE #IndexColumns VARCHAR(MAX)
DECLARE #IncludedColumns VARCHAR(MAX)
SET #IndexColumns = ''
SET #IncludedColumns = ''
DECLARE CursorIndexColumn CURSOR
FOR
SELECT col.name ,
ixc.is_descending_key ,
ixc.is_included_column
FROM sys.tables tb
INNER JOIN sys.indexes ix ON tb.object_id = ix.object_id
INNER JOIN sys.index_columns ixc ON ix.object_id = ixc.object_id
AND ix.index_id = ixc.index_id
INNER JOIN sys.columns col ON ixc.object_id = col.object_id
AND ixc.column_id = col.column_id
WHERE ix.type > 0
AND ( ix.is_primary_key = 0
OR ix.is_unique_constraint = 0
)
AND SCHEMA_NAME(tb.schema_id) = #SchemaName
AND tb.name = #TableName
AND ix.name = #IndexName
ORDER BY ixc.index_column_id
OPEN CursorIndexColumn
FETCH NEXT FROM CursorIndexColumn INTO #ColumnName, #IsDescendingKey,
#IsIncludedColumn
WHILE ( ##fetch_status = 0 )
BEGIN
IF #IsIncludedColumn = 0
SET #IndexColumns = #IndexColumns + #ColumnName
+ CASE WHEN #IsDescendingKey = 1 THEN ' DESC, '
ELSE ' ASC, '
END
ELSE
SET #IncludedColumns = #IncludedColumns + #ColumnName
+ ', '
FETCH NEXT FROM CursorIndexColumn INTO #ColumnName,
#IsDescendingKey, #IsIncludedColumn
END
CLOSE CursorIndexColumn
DEALLOCATE CursorIndexColumn
SET #IndexColumns = SUBSTRING(#IndexColumns, 1, LEN(#IndexColumns) - 1)
SET #IncludedColumns = CASE WHEN LEN(#IncludedColumns) > 0
THEN SUBSTRING(#IncludedColumns, 1,
LEN(#IncludedColumns) - 1)
ELSE ''
END
-- print #IndexColumns
-- print #IncludedColumns
SET #TSQLScripCreationIndex = ''
SET #TSQLScripDisableIndex = ''
SET #TSQLScripCreationIndex = 'CREATE ' + #is_unique + #IndexTypeDesc
+ ' INDEX ' + QUOTENAME(#IndexName) + ' ON '
+ QUOTENAME(#SchemaName) + '.' + QUOTENAME(#TableName) + '('
+ #IndexColumns + ') '
+ CASE WHEN LEN(#IncludedColumns) > 0
THEN CHAR(13) + 'INCLUDE (' + #IncludedColumns + ')'
ELSE ''
END + CHAR(13) + 'WITH (' + #IndexOptions + ') ON '
+ '[SC_LE]([Id])' + ';'
IF #is_disabled = 1
SET #TSQLScripDisableIndex = CHAR(13) + 'ALTER INDEX '
+ QUOTENAME(#IndexName) + ' ON ' + QUOTENAME(#SchemaName)
+ '.' + QUOTENAME(#TableName) + ' DISABLE;' + CHAR(13)
--print #TSQLScripCreationIndex
--print #TSQLScripDisableIndex
FETCH NEXT FROM CursorIndex INTO #SchemaName, #TableName, #IndexName,
#is_unique, #IndexTypeDesc, #IndexOptions, #is_disabled,
#FileGroupName
END
CLOSE CursorIndex
DEALLOCATE CursorIndex
The issue here is probably where you call FILEGROUP_NAME() in the SELECT clause of the definition of CursorIndex. As per the MSDN definition, the filegroup_id parameter passed to FILEGROUP_NAME() is of type smallint. I expect you have one or more records in sys.indexes which have a data_space_id value greater than 32,767 (the maximum value which can be stored in a smallint variable).
You can check by running:
SELECT SCHEMA_NAME(t.schema_id) [schema_name] ,
t.name AS TableName,
ix.name AS IndexName,
ix.data_space_id
FROM sys.tables t
INNER JOIN sys.indexes ix ON t.object_id = ix.object_id
WHERE ix.type > 0
AND ix.is_primary_key = 0
AND ix.is_unique_constraint = 0
AND t.is_ms_shipped = 0
AND ix.data_space_id > 32767
ORDER BY SCHEMA_NAME(t.schema_id),
t.name,
ix.name
This will return any indexes with this problem. I can see two ways to fix your query:
Omit the FILEGROUP_NAME() call from the original cursor definition and subsequent FETCH calls - it doesn't look like you use it for anything later on, so there's no need for it to be included.
Amend the WHERE clause of the original cursor definition to exclude any indexes with data_space_id values greater than 32767. Note that this approach will mean some indexes are not included in your cursor, but these will only be the ones which have been causing it to fail anyway.
As for why SQL Server allows values greater than 32767 in sys.indexes.data_space_id while FILEGROUP_NAME() requires a smallint parameter, I have no idea - maybe someone else can enlighten us on this?
how to remove leading zero from this
number RESULT WOULD BE LIKE THIS
00000.9 .9
A0001.1 A1.1
G0101.3 G101.3
00808.8 808.8
J0000.5 J.5
declare #input varchar(10);
declare #output varchar(10);
set #input = '00000.9';
while ((ISNUMERIC(substring(#input,1,1)) = 0) or (substring(#input,1,1) = '0'))
begin
if substring(#input,1,1) = '0'
begin
set #input = substring(#input,2,len(#input) )
end
else
if ISNUMERIC(substring(#input,1,1)) = 0
begin
set #output = substring(#input,1,1);
set #input = substring(#input,2,len(#input))
end
end
if LEN(#output) > 0
set #input = #output + #input
select #input
#input is your input
ALTER FUNCTION NUMBER(#NUMBER VARCHAR(7))
RETURNS VARCHAR(7)
AS
BEGIN
DECLARE #NUM VARCHAR(1)
DECLARE #NUM1 VARCHAR(7)
SET #NUM= SUBSTRING(#NUMBER,1,1)
IF(#NUM LIKE '[A-Z%]')
BEGIN
SET #NUM1=#NUM+''+CAST(CONVERT(FLOAT,SUBSTRING(#NUMBER,2,7),2)AS VARCHAR(7))
END
ELSE
BEGIN
SET #NUM1=LTRIM(STR(cast(#NUMBER as float),case when len(cast(#NUMBER as float)) > 7 then 7 else len(cast(#NUMBER as float)) end,1))
END
RETURN #NUM
END