Sybase Sequence - sequence

I am creating a sequence in sybase but getting mentioned exception, can anyone please help?
CREATE OR REPLACE SEQUENCE dbo.event_id_sequence
START WITH 100
INCREMENT BY 1
MINVALUE 100
NO MAXVALUE
NO CACHE
NO CYCLE
go
GRANT USAGE ON SEQUENCE dbo.event_id_sequence TO userID maintenance
GRANT USAGE ON SEQUENCE dbo.event_id_sequence TO userID readonly
GRANT USAGE ON SEQUENCE dbo.event_id_sequence TO userID reports
go
Exception:
[Error] Script lines: 1-14 -------------------------
Incorrect syntax near the keyword 'REPLACE'.
Msg: 156, Level: 15, State: 2
[Executed: 7/7/14 2:06:02 PM EDT ] [Execution: 0/ms]
[Error] Script lines: 15-19 ------------------------
Incorrect syntax near 'USAGE'.
Msg: 102, Level: 15, State: 84
[Error] Script lines: 15-19 ------------------------
Incorrect syntax near 'USAGE'.
Msg: 102, Level: 15, State: 84
[Error] Script lines: 15-19 ------------------------
Incorrect syntax near 'USAGE'.
Msg: 102, Level: 15, State: 84
[Executed: 7/7/14 2:06:02 PM EDT ] [Execution: 0/ms]

Sybase ASE does not have sequence, the code you found is likely pulled from Sybase IQ or possible SQL Anywhere.
Instead of using sequence, you should look at using IDENTITY columns instead.
If that does not suit your needs, Sybase suggests a number of other approaches that may give you what you are looking for.
Methods:
Methods which can be used to produce a monotonic series are:
Max Plus One
Enhanced Max Plus One
Next Key Table
Identity Property
All of these are detailed in the linked document.
I would also suggest reviewing page 20 of this presentation on Migration from Oracle to ASE from SAP Techwave. There is some sample code on how to emulate SEQUENCE using a sequence table/procedure.
CREATE TABLE my_seq (seq int)
go
//initialize the sequence
INSERT INTO my_seq select 0
go
CREATE PROCEDURE get_seq (#seq int OUTPUT)
AS UPDATE my_seq SET seq = seq+1
SELECT #seq = seq FROM my_seq
go
// execute the sp to get the next sequence number
DECLARE #seq int
EXEC get_seq #seq OUTPUT
INSERT INTO m_table VALUES (#seq,..)
go
Outdated Link - http://www.sybase.com/detail?id=860

Related

Trying to add a column to SQL Server table

I am getting incorrect syntax errors with the following statement (SQL Server 2017)
USE ToDo
GO
ALTER TABLE tasks ADD COLUMN completed TINYINT(1);
Started executing query at Line 1
Commands completed successfully.
20:31:38Started executing query at Line 3
Msg 156, Level 15, State 1, Line 3
Incorrect syntax near the keyword 'COLUMN'.
A very similar syntax was used to remove a column that worked fine.
This code would run in MySQL - but not on SQL Server. Consider:
alter table tasks add completed tinyint;
Rationale:
alter table does not support column in SQL Server; just remove that keyword
the tinyint datatype does not take a length

Can't drop a view inside a function

I'm trying to make a simple function to return a random eye color. I could do this in a stored procedure but I was trying to challenge my self and try something new. I'm getting some errors, I've tried this a few different ways and I have found some documents roughly related but I'm just not skilled enough I think to understand what I did wrong and what the documents I've found are referring too syntax wise. I hope that makes sense.
CREATE FUNCTION Random_Eyes ()
RETURNS NVARCHAR(100)
AS
BEGIN
CREATE VIEW Rand_Eyes
AS
SELECT TOP 1 [Eyes]
FROM [dbo].[Eyes]
ORDER BY NEWID()
GO
DECLARE #Eyes AS NVARCHAR(100) = (SELECT [Eyes] FROM Rand_Eyes)
RETURN #Eyes
DROP VIEW Rand_Eyes
END
GO
Errors:
Msg 156, Level 15, State 1, Procedure Random_Eyes, Line 14
Incorrect syntax near the keyword 'VIEW'.
Msg 102, Level 15, State 1, Procedure Random_Eyes, Line 14
Incorrect syntax near ')'
Msg 178, Level 15, State 1, Line 4
A RETURN statement with a return value cannot be used in this context.
Msg 102, Level 15, State 1, Line 7
Incorrect syntax near 'END'.
Any feedback or suggestions would be helpful. Thank you
You don't need a temporary view inside a function - that's not even allowed anyway as functions in SQL Server are strictly read-only: they cannot perform any DDL operations (CREATE, UPDATE, INSERT, DELETE).
Note that ORDER BY NEWID() is not the best way to get a random result (because it triggers a table linear scan). Try this:
CREATE FUNCTION Random_Eyes()
RETURNS NVARCHAR(100)
AS
BEGIN
DECLARE #count int = ( SELECT COUNT(*) FROM [Eyes] )
SELECT
Eyes
FROM
dbo.Eyes
ORDER BY
EyeId -- or whatever your constant, incrementing primary-key is
OFFSET
( RAND() * #count ) ROWS
FETCH NEXT
1 ROWS ONLY
END

How to return multiple errors in a single Query

My goal is to catch error message from SQL query, log or print then pass it instead of letting it generate a real error. but I found it's not possible to catch multiple errors from the examining query; only the last error will be caught:
DECLARE #ErrorMessage varchar(1000)
BEGIN TRY
EXEC('SELECT AA,BB FROM TABLE')--neither column AA nor BB exists
END TRY
BEGIN CATCH
SET #ErrorMessage = 'ERRORMESSAGE: ' + Error_Message()
PRINT #ErrorMessage
END CATCH
The query will only give feedback that column BB cannot found, but cannot show that AA column also doesn't exist.
Or another example, by putting this query in TRY block
EXEC('CREATE SCHEMA abc AUTHORIZATION [dbo]') --schema abc already exists
It will acutally raise error 'schema already exists' first, then another error 'cannot create schema, see previous error', but now the 1st key error containing key information has been 'eaten'.
How to show all of the error messages then?
YOU CAN STILL USE RAISERROR INSIDE TRY-CATCH BLOCKS
Ivan is right about ERROR_MESSAGE and how TRY-CATCH may remove the robust nature of your query, however, this only occurs when the SEVERITY of the message is above 10 in a TRY block. So the trick is to set the severity under 11.
The error is returned to the caller if RAISERROR is run:
Outside the scope of any TRY block.
With a severity of 10 or lower in a TRY block.
With a severity of 20 or higher that terminates the database
connection.
MSDN - RAISERROR
RAISERROR can be used as a substitute for PRINT and allows for custom messages. Furthermore, you can set the STATE to different numbers to keep track of similar, but different errors in your code.
Since Fatal errors will be your bane, I suggest you test queries and DDL commands before running them. For example, instead of blindly attempting EXEC('CREATE SCHEMA abc AUTHORIZATION [dbo]'), you can try this ad-hoc message instead:
DECLARE #SCHEMA NVARCHAR(10)
DECLARE #Message NVARCHAR(255)
SET #SCHEMA = N'abc'
SET #Message = N'The Schema ' + #SCHEMA + ' already exists.'
IF SCHEMA_ID(#SCHEMA) IS NOT NULL
EXEC('CREATE SCHEMA abc AUTHORIZATION [dbo]')
ELSE RAISERROR(#Message, 10, 1)
--result: The Schema abc already exists.
There are many ways of checking the validity of dynamic SQL, DDL, and DML, including useful functions like OBJECT_ID, OBJECT_NAME, DATABASE_ID, etc where you test safely, and then run the appropriate RAISERROR message for each error.
Remove TRY-CATCH, if possible - divide script statements into many separate batches with GO.
TRY-CATCH reacts on first exception and breaks execution of TRY-block:
If an error occurs in the TRY block, control is passed to another
group of statements that is enclosed in a CATCH block.
https://msdn.microsoft.com/en-us/library/ms175976.aspx
So behaviour of TRY-CATCH is rather opposite to your intention.
GO sets the end of the batch. Many of errors don't even break the batch, because they have low severity, so for some cases there is no need even to split script into many batches.
As an example here is sample dummy script for testing or some utility purpose (not for production of course) that generates many errors:
create proc SomeProc as
begin
exec('select uknown from non_existent')
end
GO
drop table #test1
drop table #test2
GO
drop table #test3
GO
create table #test1 (id int primary key)
insert into #test1(id)
exec SomeProc
insert into #test
values (1)
insert into #test1
values (1)
GO
insert into #test1
values (11)
insert into #test1
values (11)
insert into #test
values (22)
GO
select * from #test1
GO
drop table #test
GO
drop table #test
drop proc SomeProc
select object_id('SomeProc', 'P')
GO
it does give the output of selects:
and all the messages:
Msg 3701, Level 11, State 5, Line 7 Cannot drop the table '#test2',
because it does not exist or you do not have permission.
Msg 3701,
Level 11, State 5, Line 9 Cannot drop the table '#test3', because it
does not exist or you do not have permission.
Msg 208, Level 16, State
1, Line 11 Invalid object name 'non_existent'.
(0 row(s) affected)
Msg 208, Level 16, State 0, Line 16 Invalid object
name '#test'.
(1 row(s) affected)
Msg 2627, Level 14, State 1, Line 25 Violation of
PRIMARY KEY constraint 'PK__#test1____3213E83FF35979C1'. Cannot insert
duplicate key in object 'dbo.#test1'. The duplicate key value is (11).
The statement has been terminated.
Msg 208, Level 16, State 0, Line 28
Invalid object name '#test'.
(1 row(s) affected)
Msg 3701, Level 11, State 5, Line 33 Cannot drop
the table '#test', because it does not exist or you do not have
permission.
Msg 3701, Level 11, State 5, Line 35 Cannot drop the table
'#test', because it does not exist or you do not have permission.
"My goal is to catch error message from SQL query, log or print then pass it instead of letting it generate a real error." - if "print" is ok then just remove TRY-CATCH.
Run the script through sqlcmd and redirect errors to a file:
How to get SQLCMD to output errors and warnings only.
sqlcmd -i Script.sql -E -r1 1> NUL

OPENQUERY throws error when used with WIN2K8\SQL2K12

I'm trying the following Sql query to move my stored procedure result into table
SELECT *
INTO #tmpTable
FROM OPENQUERY(WIN2K8\SQL2K12, 'EXEC vcs_gauge #gauge_name=vs1_bag,#first_rec_time=2014-09-01 09:00:00,#last_rec_time=2014-09-01 10:00:00')
following error is thrown, when I execute the query.
Incorrect syntax near '\'.
I don't want to add linked server .How to resolve this issue?
EDIT1
When I do [win2k8\sql2k12], and first execute the following command
EXEC sp_serveroption 'YourServer', 'DATA ACCESS', TRUE
A new message comes
OLE DB provider "SQLNCLI11" for linked server "WIN2K8\SQL2K12" returned message "Deferred prepare could not be completed.".
Msg 8180, Level 16, State 1, Line 1
Statement(s) could not be prepared.
Msg 102, Level 15, State 1, Line 1
Incorrect syntax near '-'.
You need to enclose DATETIME values in single quotes. And since your query is in a string itself, those single-quotes need to be doubled / escaped as follows (and you should probably also put the first parameter's value in escaped-single-quotes as it is clearly a string).
You should also fully qualify the stored procedure name with [DatabaseName].[SchemaName]..
And since the vcs_gauge proc uses Dynamic SQL, you need to specify the WITH RESULT SETS clause. For more info on this clause, please see the MSDN page for EXECUTE.
SELECT *
INTO #tmpTable
FROM OPENQUERY([WIN2K8\SQL2K12],
N'EXEC [DatabaseName].[SchemaName].vcs_gauge
#gauge_name = ''vs1_bag'',
#first_rec_time = ''2014-09-01 09:00:00'',
#last_rec_time = ''2014-09-01 10:00:00''
WITH RESULT SETS ( { column_specification} );
');

Msg 8152, Level 16, State 14, Line XXX String or binary data would be truncate

Scenario: A large stored procedure is run thousands of time a day, 6 days a weeks every year. For this one specific situation I'm getting an error
Msg 8152, Level 16, State 14, Line 114
String or binary data would be truncated
This stored procedure is about 800 lines of code, with lots of parameters, lots of variables and lots of tables.
Go
#exampleParam varchar(30)
#exampleParam datetime
DECLARE #declaredvara VARCHAR(50);
DECLARE #declaredvarb VARCHAR(50); -- where the line error is according to the printout
DECLARE #declaredvarc VARCHAR(50);
DECLARE #declaredvard VARCHAR(50); -- where line error is adjusted for comments in front of GO
BEGIN TRANS
-- some calculations (700+ lines)
COMMIT TRANS
--error catch
ROLLBACK TRANS
Problem: I'm want to know if its possible to get an accurate Line error read, so I can at least narrow down which tables I have to check. There are tons of tables involved in this stored procedure.
*** Both declared variables(before and after adjustment of GO) it points to are dead weight, they're nvr used.
Bonus info: I ran the stored procedure with params populated and params = '' except for the datetimes. In both cases I got the same error. However, I know the stored procedure works because it's being used thousands of times a day w/out this error.
EXEC SP '','','','','2014-11-6'
EXEC SP 'XX_XX_XX','',1,'','2014-11-6'
--both return the same error of Msg 8152, Level 16, State 14
--XX is a specific serialnum.
--However all other serialnum have no problem
EDIT: The DB is running SQL Server 2005
EDIT2: I'm using SQL Server 2008 to edit. - So debug isn't an option
Used that it will fix Msg 8152, Level 16, State 14, Line 114
String or binary data would be truncated.
SET ansi_warnings OFF
GO
BEGIN CATCH
DECLARE #body VARCHAR(4000)
SET #body='<b>Exception in spname </b><br/>'
SET #body=#body + ( SELECT
'<b>Error No :</b> '+ CONVERT(VARCHAR(100),ERROR_NUMBER()) +'<br/>'
+'<b>Error Severity :</b> '+CONVERT(VARCHAR(1000),ERROR_SEVERITY()) +'<br/>'
+'<b>Error State :</b> '+CONVERT(VARCHAR(1000),ERROR_STATE()) + '<br/>'
+'<b>Error Procedure :</b> '+CONVERT(VARCHAR(1000),ERROR_PROCEDURE())+'<br/>'
+'<b>Error Line :</b> '+CONVERT(VARCHAR(100),ERROR_LINE())+'<br/>'
+'<b>Error Message :</b> '+CONVERT(VARCHAR(2000),ERROR_MESSAGE()));
END CATCH
This error indicates that you are going to store some thing bigger that it's storage. you may need to check if you are going to store some string with more that 50 characters in #declaredvara or #declaredvarb or #declaredvarc or #declaredvard or any other variables or table columns. for example you may define #test as varchar(2) and then try to insert 'vahid' into it. in this case similar exception will be thrown. There is 2 way(as I know) that you can find the error ocurance line:
If you need to find the exact line of error occurrence you may need to debug you SP using sql server debug tools(Read more about debugging in Sql Server here)
You can also use TRY...CATCH blocks to check which block of code in you SP causes the error.
It turns out one of the variables in the area was declared but never given a value.
That variable was later used as a param in executing another stored procedure from within.
Which resulted in a null param being passed into a param that couldn't contain it.
Thanks everyone for the responses.
if your inserting in varchar(3) and selecting from varchar(10), you are getting the error. You have to design them same as varchar(3) or varchar(10).