I am getting following Error message while creating IBM db2 procedure - database

What is wrong with the following code?
PROCEDURE DATETYPE DYNAMIC RESULT SETS 1 LANGUAGE SQL
BEGIN
DECLARE #DateType TABLE
( LABEL CHAR(30) ,
Value VARCHAR(1) );
DECLARE C CURSOR WITH RETURN FOR;
INSERT
INTO
#DateType
VALUES ('Paid Dates Only',
'P') INSERT
INTO
#DateType
VALUES('Incurred Dates with Paid',
'S') SELECT
*
FROM
#DateType;
OPEN C;
END
I am using db2 and gets the following error:
SQL Error [42601]: An unexpected token "( LABEL CHAR(30) , Value VARCHAR(1) )" was found following " ". Expected tokens may include: "E #DateType TABLE ".. SQLCODE=-104, SQLSTATE=42601, DRIVER=4.21.29

wichever DB2 it is (db2-400 or db2-luw) DECLARE xx TABLE is not DB2 SQL PL syntax
Btw if I understand it well your code can be replaced with a view
CREATE OR REPLACE VIEW DATETYPE (LABEL, VALUE) as (
VALUES
('Paid Dates Only', 'P'),
('Incurred Dates with Paid', 'S')
)
edit:since it has to be a prodecure, then you can use
CREATE OR REPLACE PROCEDURE DATETYPE ()
RESULT SETS 1
LANGUAGE SQL
BEGIN
DECLARE DATAS CURSOR WITH RETURN FOR
VALUES
('Paid Dates Only', 'P'),
('Incurred Dates with Paid', 'S');
OPEN DATAS;
END

Related

How to find exact row where SQL query fail

I'm using SQL Server 2008 R2. I have 2 tables old and new and about 500k rows.
I need to convert data from old to new. Some columns were changed. For example in old table many columns are of type varchar and in new table int.
I'm executing query like this:
INSERT INTO new (xxx)
SELECT FROM old (yyy)
And get following error:
Msg 245, Level 16, State 1, Line 4
Conversion failed when converting the nvarchar value 'Tammi ' to data type int.
This error shows, that in old table are some rows with wrong data in columns. (Human factor).
But how can I find these wrong rows? Is it possible?
How can I find in what column wrong data is present?
This is a pain. But, to find values that cannot be converted to ints, try this:
select yyyy
from old
where yyyy like '%[^0-9]%';
In SQL Server 2012+, you can use try_convert():
select yyyy
from old
where try_convert(int, yyyy) is null;
Could you execute the code that this T-SQL statement generates (just change the table name):
DECLARE #TableName SYSNAME = 'DataSource'
SELECT 'SELECT * FROM ' + #TableName + ' WHERE ' +
STUFF
(
(
SELECT 'OR ISNUMERIC([' + name + '] + ''.e0'') = 0 '
FROM sys.columns
WHERE object_id = OBJECT_ID(#TableName)
FOR XML PATH(''), TYPE
).value('.', 'VARCHAR(MAX)')
,1
,3
,''
);
For, example, if we have the following table:
IF OBJECT_ID('DataSource') IS NOT NULL
BEGIN
DROP TABLE DataSource;
END;
GO
CREATE TABLE DataSource
(
A VARCHAR(12)
,B VARCHAR(12)
,C VARCHAR(12)
);
GO
INSERT DataSource ([A], [B], [C])
VALUES ('1', '2', '3')
,('0.5', '4', '2')
,('1', '2', 'A');
GO
The script will generate this statement:
SELECT * FROM DataSource WHERE ISNUMERIC([A] + '.e0') = 0 OR ISNUMERIC([B] + '.e0') = 0 OR ISNUMERIC([C] + '.e0') = 0
returning two of the rows (because A and 0.5 cannot be converted to int):

Convert varchar to DateTime not working on table but works on individual values

I have a table with column ImportDate of datatype varchar(100).
I want to convert its values from varchar to Datetime and for that I have used this query:
select
convert(datetime, ImportDate)
from ImportHistory
But it throws an exception with message
Msg 241, Level 16, State 1, Line 1
Conversion failed when converting date and/or time from character string.
But when I individually select each value and run the statement it works fine. For example the below query works perfectly, and so do all the values in the table
select convert(Datetime, '1826-07-04 18:20:00')
There are no null values in that table and below are the values:
1826-07-04 18:20:00
1826-07-04 18:20:00
1917-11-08 11:11:00
2003-07-16 16:02:00
1984-06-08 00:00:00
2004-06-05 00:00:00
1826-07-04 18:20:00
1826-07-04 18:20:00
1917-11-08 11:11:00
2003-07-16 16:02:00
1984-06-08 00:00:00
2004-06-05 00:00:00
If you're using SQL Server 2012+, use TRY_PARSE or TRY_CONVERT in this kind of scenario:
DECLARE #ImportHistory TABLE (ImportDate VARCHAR(100))
INSERT #ImportHistory
VALUES
('1826-07-04 18:20:00'),
('1826-07-04 18:20:00'),
('1917-11-08 11:11:00'),
('2003-07-16 16:02:00'),
('1984-06-08 00:00:00'),
('2004-06-05 00:00:00'),
('1826-07-04 18:20:00'),
('1826-07-04 18:20:00'),
('1917-11-08 11:11:00'),
('Invalid!'),
('2003-07-16 16:02:00'),
('1984-06-08 00:00:00'),
('2004-06-05 00:00:00')
SELECT
ImportDate, TRY_CONVERT(datetime, ImportDate) as dt
FROM #ImportHistory
WHERE TRY_CONVERT(datetime, ImportDate) IS NULL
-- output: Invalid!, NULL
To find the invalid value. If you want invalid values to be converted to NULL, you can remove the WHERE clause and just use TRY_PARSE in place of CONVERT.
The dates you've listed are all valid, but it's very likely in your actual table you have at least one invalid date - or at least not one that can be parsed as is (extra space, month/day stored in different culture format, etc.).
If you must keep your column as a VARCHAR for some unknown reason and you want to make sure that applications don't insert unparsable dates into it, you could add a constraint
ALTER TABLE ImportHistory
ADD CONSTRAINT CK_ImportDate
CHECK(TRY_CONVERT(datetime, ImportDate) IS NOT NULL)
If you don't have SQL Server 2012+, you could try making a cursor to find the invalid data:
DECLARE #dt VARCHAR(100);
DECLARE #dt2 DATETIME;
BEGIN TRY
DECLARE test_cursor1 CURSOR FOR
SELECT Importdate FROM #ImportHistory
OPEN test_cursor1
WHILE ##FETCH_STATUS = 0
BEGIN
FETCH NEXT FROM test_cursor1 INTO #dt
SET #dt2 = CONVERT(datetime, #dt)
END
END TRY
BEGIN CATCH
SELECT #dt
END CATCH
-- output: Invalid!
This resolved the issue.
Select Convert(Datetime, LTRIM ( RTRIM ( REPLACE ( REPLACE ( REPLACE ( ImportDate, CHAR(10), ''), CHAR(13), ''), CHAR(9), '') ) )) from ImportHistory
Thank you All !!

SQL Server : Verify a list of text from a table

Could you please help me with a query for the following requirements?
I have a list of Cities which I want to verify from a table. The query will have the Input List (below) in the where clause and gives me results like shown below in expected result.
Input list = ('City1','City2','City3','City4',.......'City100')
Expected result
1. City1 Exist
2. City2 Exist
3. City3 Not Exist
4. City4 Exist
5. City5 Not Exist
Thanks.
Try it like this: Just paste my code into an empty query window and execute. Adapt to your needs (most important is to replace the "#ExistingCities" with your actual table's name):
First I declare a "table" with some already existing cities (3 and 5 are missing). The input string misses City4.
DECLARE #ExistingCities TABLE(CityName VARCHAR(100));
INSERT INTO #ExistingCities VALUES('City1'),('City2'),('City4'),('City6');
DECLARE #Input VARCHAR(MAX)='City1,City2,City3,City5,City6';
WITH SplittedInput AS
(
SELECT CAST('<x>' + REPLACE(#input,',','</x><x>') + '</x>' AS XML) AS CitiesAsXml
)
SELECT oneCity.value('.','varchar(max)') AS InputName
,CASE WHEN exC.CityName IS NOT NULL THEN 'Exist' ELSE 'Not Exist' END AS ResultCode
FROM SplittedInput
CROSS APPLY CitiesAsXml.nodes('/x') AS InputCity(oneCity)
LEFT JOIN #ExistingCities AS exC ON exC.CityName=oneCity.value('.','varchar(max)')
Please check following SQL script,
For demo I created a sql CityList table with sample data
create table cityList (id int identity(1,1), city nvarchar(50),)
insert into cityList(city) values ('City1'),('City3')
declare #input nvarchar(max) = 'City1,City2,City3,City4,City100'
select
s.val,
case when c.city is not null then 'Exist' else 'Not Exist' end
from dbo.split(#input,',') s
left join cityList c on c.city = s.val
Please note that you need the SQL string Split function codes for dbo.split() function
I hope it helps

Error converting data type varchar to numeric. SQL Server

I'm writing data on the Sql Server database.
When data is written, a trigger runs.
TRIGGER
ALTER TRIGGER Alert ON records AFTER INSERT AS
BEGIN
DECLARE #tempmin decimal = 0
DECLARE #current_max_idAlarm int = (SELECT MAX(IdAlarm) FROM alarms)
DECLARE #maxidAlarm int
DECLARE #temp decimal = (SELECT s.lim_inf_temp from sensores s JOIN inserted i ON s.idSensor=i.idSensor )
-- Insert into alares from the inserted rows if temperature less than tempmin
SET IDENTITY_INSERT alarmes On
INSERT alarmes (IdAlarm, desc_alarm,date, idRecord)
SELECT
ROW_NUMBER() OVER (ORDER BY i.idRecord) + #current_max_idAlarm, 'Temp Error', GETDATE(), i.idRecord
FROM
inserted AS i
WHERE
i.Temperature < #temp
end
INSERT
insert into record values ('2014-05-26' ,'14:51:47','Sensor01','---','48.6','9.8');
Whenever I try to record this type of data: '---'
Gives the following error:
Msg 8114, Level 16, State 5, Procedure Alert, Line
Error converting data type varchar to numeric.
I know it is to be in decimal type (DECLARE #temp decimal - TRIGGER), but moving to the type varchar to trigger stops working correctly.
Does someone can help me resolve this error please?
Thank you all.
You are trying to insert --- inside a numeric column, you simply can't do that.
You have mainly 2 options:
Change the data type of the destination column
Choose a different value to insert (like NULL)

Create #TableVariable based on an existing database table?

I want to use table variables in stored procedures but here is an issue. My tables are very large and declaring a table variable need a long code to write and debug as well.
Kindly advice me some way to declare table variables quickly, is it possible to create table variable based on an existing table ?
Or please share any tip to create code for creating table variable.
Thanks
Right click the table, choose Script As Create.
Replace create table xxx with declare #xxx table.
As discussed in this SO Question you can't select into a table variable.
When you say "large", if you mean a lot of columns, the best approach for you would probably be to script that table as create and save the definition and use that in your Declare statement.
If you mean large as far as the number of rows you'll have in the table variable, you may want to consider using a temporary table which you could then do a SELECT INTO statement to create it based off of the original.
SELECT * INTO #tmpTable FROM srcTable
The simple answer is "No you cannot create a variable table based on other table"
But, you can generalise a bit by using a type table.
For example (note: you can add documentation to the type table and columns, which can be useful for future reference):
PRINT 'type: [dbo].[foo_type]'
PRINT ' - Check if [dbo].[foo_type] TYPE exists (and drop it if it does).'
GO
IF EXISTS (SELECT 1 FROM sys.types WHERE name = 'foo_type' AND is_table_type = 1 AND SCHEMA_ID('dbo') = schema_id)
BEGIN
-- Create the proc
PRINT ' - Drop TYPE [dbo].[foo_type]';
DROP TYPE [dbo].[foo_type];
END;
GO
PRINT ' - create [dbo].[foo_type] TYPE.'
GO
CREATE type [dbo].[foo_type] as Table
(
[id] int identity(1,1) PRIMARY KEY
, [name] varchar(255) NOT NULL
, [description] varchar(255)
, numeric_data numeric(26, 6)
, datetimestamp datetime default getdate()
, Unique_Indicator float unique not null default cast(getdate() as float)
, CHECK (Unique_Indicator > 0)
);
GO
PRINT ' - done.'
GO
-- Adding the descriptions
PRINT ' - Adding Type level Description'
EXEC sys.sp_addextendedproperty #name=N'MS_Description', #value=N'describe the usage of this type.' , #level0type=N'SCHEMA',#level0name=N'dbo', #level1type=N'TYPE',#level1name=N'foo_type'
GO
PRINT ' - Adding Column level Descriptions'
PRINT ' - column: id'
EXEC sys.sp_addextendedproperty #name=N'MS_Description', #value=N'ID of the record...' , #level0type=N'SCHEMA',#level0name=N'dbo', #level1type=N'TYPE',#level1name=N'foo_type', #level2type=N'COLUMN',#level2name=N'ID';
GO
------------------------------------------------------------------------------------------------
-- use the type defined above to manipulate the variable table:
declare #foo_table foo_type;
--insert using the default value for the for the unique indicator.
insert into #foo_table (name, [description], numeric_data, datetimestamp)
values('babar', 'this is the king of the elephants', 12.5, '1931-01-01')
;
-- insert the records one by one to use the scope_identity() for the unique indicator.
insert into #foo_table (name, [description], numeric_data, datetimestamp, Unique_Indicator )
values('zephyr', 'Babar''s monkey friend', 5.5, '1932-01-01', scope_identity())
;
insert into #foo_table (name, [description], numeric_data, datetimestamp, Unique_Indicator )
values ('Celeste', 'Babar''s sister', 19.5, '1932-01-01', scope_identity())
;
-- insert using a list of values
insert into #foo_table (name, [description], numeric_data, datetimestamp, Unique_Indicator )
values('Babur', 'Not Babar!!!', 1483, '1983-02-14', 10)
, ('Mephistopheles', 'Not Babar either...', 666, '1866-01-01',11)
;
-- insert using a select
insert into #foo_table (name, [description], numeric_data, datetimestamp, Unique_Indicator)
(select 'Conan', 'The Cimmerian barbarian', 850, '1932-12-01',99 union
select 'Robert E. Howard', 'Conan''s creator', 30, '1906-01-22', 100
);
-- check the data we inserted in the variable table.
select * from #foo_table;
-- Clean up the example type
DROP TYPE [dbo].[foo_type];

Resources