HSQLDB SqlTool is throwing user lacks privilege or object not found - hsqldb

I'm executing .sql scripts using SqlTool. It keep on saying user lacks privilege or object not found. The same script is working perfectly from Swing UI.
My Script (hello.sql)
\.
SET DATABASE SQL SYNTAX ORA TRUE;
ALTER CATALOG PUBLIC RENAME TO SOMENAME;
COMMIT;
CREATE SCHEMA SOMESCHEMA;
COMMIT;
CREATE PROCEDURE SOMENAME.SOMESCHEMA.SP_FAILED_COUNT(IN i_ssn VARCHAR(100), IN i_page_id NUMBER(10), IN i_ip_address VARCHAR(100), IN i_session_guid VARCHAR(100), OUT o_toomanyfails VARCHAR(2000))
READS SQL DATA
BEGIN ATOMIC
SET o_toomanyfails = 'N';
END
COMMIT;
.
:;
Exception
> java -jar sqltool-2.4.1.jar --autocommit --rcfile C:\\my-files\\hsqldb\\2.4.1\\dbmanager.rc web C:\\my-files\\hsqldb\\2.4.1\\hello.sql
Executing command from edit buffer:
"SET DATABASE SQL SYNTAX ORA TRUE;
ALTER CATALOG PUBLIC RENAME TO SOMENAME;
COMMIT;
CREATE SCHEMA SOMESCHEMA;
COMMIT;
CREATE PROCEDURE SOMENAME.SOMESCHEMA.SP_FAILED_COUNT(IN i_ssn VARCHAR(100), IN i_page_id NUMBER(10), IN i_ip_address VARCHAR(100), IN i_session_guid VARCHAR(100), OUT o_toomanyfails VARCHAR(2000))
READS SQL DATA
BEGIN ATOMIC
SET o_toomanyfails = 'N';
END
COMMIT;"
SEVERE SQL Error at 'C:\my-files\hsqldb\2.4.1\hello.sql' line 14:
"SET DATABASE SQL SYNTAX ORA TRUE;
ALTER CATALOG PUBLIC RENAME TO SOMENAME;
COMMIT;
CREATE SCHEMA SOMESCHEMA;
COMMIT;
CREATE PROCEDURE SOMENAME.SOMESCHEMA.SP_FAILED_COUNT(IN i_ssn VARCHAR(100), IN i_page_id NUMBER(10), IN i_ip_address VARCHAR(100), IN i_session_guid VARCHAR(100), OUT o_toomanyfails VARCHAR(2000))
READS SQL DATA
BEGIN ATOMIC
SET o_toomanyfails = 'N';
END
COMMIT;"
user lacks privilege or object not found: SOMENAME
org.hsqldb.cmdline.SqlTool$SqlToolException
The same script is working from HSQLDB Swing UI.
I tried adding commit but still it is not working. It is working fine if I remove catalogname.schemaname.(SOMENAME.SOMESCHEMA.) from script
Also, i didn't understand one thing.
If I execute the following command in Swing UI it working perfectly for first time but if i execute for the second time i get the following exception
user lacks privilege or object not found: PUBLIC / Error Code: -5501 / State: 42501
ALTER CATALOG PUBLIC RENAME TO SOMENAME;
It confirms that the catalog is renamed. But where if I run the same script using sqltool again and again it never throws the same exception. How to make it working from sqltool (i.e. after importing it from .sql script)

There's no way that "The same script is working from HSQLDB Swing UI."
I loaded the exact script into HSQLDB Swing UI v. 2.4.1 and it fails as I expected with "unknown token: / Error Code: -5582 / State: 42582" because you have SqlTool-specific grammar in your script.
If I remove the Sql-Tool specific grammar then Swing UI reports "user lacks privilege or object not found: SOMENAME / Error Code: -5501 / State: 42501".
Fred T. can explain exactly why, but those commands apparently have to be in two transactions and I can make it work from Swing UI by just executing everything before the "CREATE SCHEMA" in one execution; then the rest in another execution. I suspect that you actually edited your script (not running "The same script") and then executed it with an older version of HyperSQL Swing UI where it did not execute all of the commands in a single transaction.
SqlTool doesn't have that limitation and allows you to control exactly what commands go over in which transaction. Just allow all commands (the COMMITs are unnecessary) in their own transactions (which is default behavior). It then works.
TIPS:
You don't need the COMMITs because these are DDL statements.
You can
execute the . transaction by terminating it with ".;" instead of
separate "." and ":." commands.
You don't need the \. at all because
SqlTool automatically knows that you need a new grouped transaction
when it sees "CREATE PROCEDURE" beginning a command. If it makes
the code more readable for you, you can insert the ".\" immediately
before the CREATE PROCEDURE.
In summary this works from SqlTool:
SET DATABASE SQL SYNTAX ORA TRUE;
ALTER CATALOG PUBLIC RENAME TO SOMENAME;
CREATE SCHEMA SOMESCHEMA;
CREATE PROCEDURE SOMENAME.SOMESCHEMA.SP_FAILED_COUNT(IN i_ssn VARCHAR(100), IN i_page_id NUMBER(10), IN i_ip_address VARCHAR(100), IN i_session_guid VARCHAR(100), OUT o_toomanyfails VARCHAR(2000))
READS SQL DATA
BEGIN ATOMIC
SET o_toomanyfails = 'N';
END
.;

Related

Unable to create DB2 Procedure through command line

I am trying to create a procedure to do a blanket revoking of executeauth for procedures from a schema. This is in line with trying to secure a non-restricted database.
CREATE PROCEDURE PROC_REV
LANGUAGE SQL
MODIFIES SQL DATA
BEGIN
DECLARE v_NAME VARCHAR(400);
FOR v1 AS
c1 CURSOR FOR
select specificname from SYSCAT.ROUTINEAUTH where grantee='PUBLIC' and schema='SYSPROC' and routinetype='P'
DO
SET v_NAME = specificname;
SET v_GrantQuery = 'revoke execute on specific procedure '|| v_NAME ||' from PUBLIC';
EXECUTE IMMEDIATE v_GrantQuery;
END FOR;
END#
and this is the command I run to process the file with the code above.
db2 -td# -svf RoutineAuthRevoke.db2
However, I keep running into this error
SQL0553N An object cannot be created with the schema name "SYSFUN ". LINE NUMBER=1. SQLSTATE 42939
I'm fairly new to DB2 and this is my first foray into writing db2 procedure scripts. Would anyone be able to spot the "SYSFUN " because I sure as hell can't. The only other way I can revoke 310 entries from SYSPROC for PUBLIC is through a batch file and I figured, procedures might be a cleaner way of achieving this. I would really appreciate any help with either this error or with the code itself.
A number of problems.
You can't create a routine in the SYSFUN schema as the error message shows. You get this message because the statement VALUES CURRENT SCHEMA returns SYSFUN in your session. You must either run the SET SCHEMA SOME_VALID_SCHEMA_NAME statement before CREATE or use fully qualified routine name like SOME_VALID_SCHEMA_NAME.PROC_REV.
Variable v_GrantQuery is not defined in the routine.
According to the syntax of REVOKE (routine privileges) statement, you should generate the REVOKE statement using fully qualified routine name and with RESTRICT clause at the end. The easiest way to do it with a compound statement (you don't need to create a routine for that):
BEGIN
FOR v1 AS
select 'REVOKE EXECUTE ON SPECIFIC PROCEDURE "' || schema ||'"."'|| specificname || '" FROM PUBLIC RESTRICT' AS STMT
from SYSCAT.ROUTINEAUTH
where grantee='PUBLIC' and schema='SYSPROC' and routinetype='P'
DO
EXECUTE IMMEDIATE v1.STMT;
END FOR;
END#

SQL Server : weird Invalid object name

I am trying to create a stored procedure and I get this error:
Msg 208, Level 16, State 6, Procedure SP_MergeStagedPoliticalPartyAgents, Line 1 [Batch Start Line 0]
Invalid object name 'SP_MergeStagedPoliticalPartyAgents'.
SQL is as follows, minus the content
CREATE OR ALTER PROCEDURE SP_MergeStagedPoliticalPartyAgents
AS
BEGIN
-- Content removed for brevity
END
If I alter the name in anyway, i.e. adding an extra s, or removing the s at the end. It works 100% fine, so my question is what is it with this particular name that I am using that is causing it to fail?
Does SQL Server have a name validation regex that this name is violating? Is it a reserved name?
Weirder addition IMO: for the sake of testing if I go:
CREATE PROCEDURE SP_MergeStagedPoliticalPartyAgents
AS
BEGIN
-- Content removed for brevity
END
It runs fine and creates the stored procedure on top of that from then onwards the CREATE OR ALTER PROCEDURE SP_MergeStagedPoliticalPartyAgents statement works fine.
It seems as if a stored procedure with this name doesn't exist it will fail on the CREATE OR ALTER PROCEDURE SP_MergeStagedPoliticalPartyAgents but pass on the CREATE SP_MergeStagedPoliticalPartyAgents if it is being initialized for the first time.
Note:
I already have other stored procedures created in the same mannerism that are fine
It is not a permissions issue as I am able to create stored procedures fine.
Running the script via VS causes the same issue so it is not related to SMSS
It also isn't the content. If I replace the content with a basic select * from table it still has the issue.
Just after I posted the issue, I found the solution.
https://bornsql.ca/blog/remember-this-if-you-want-to-use-sp_/
Create or alter
You can quite easily create a stored procedure with the prefix, both in the master database and any user databases you have, using CREATE PROCEDURE. However what Erik shows is that if you already have a stored procedure with a name that has the sp_ prefix in the master database, and then use CREATE OR ALTER syntax to create a stored procedure in a user database with the same name, you’ll get an “Invalid object name” error in the user database:*
I found that someone had created these stored procedures in the master database also.
I've got the exact same issue. SQL 2019 (15.0.4053.23)
I have run the exact same stored procedure on another database with no issues, yet on this particular database it errors. Changing the name works, removing the ALTER and only using CREATE works. if I CREATE the procedure and then use CREATE OR ALTER, it works.
CREATE OR ALTER PROCEDURE dbo.sp_bt_annl_stmt_members_select
AS
SELECT * FROM sysusers
Msg 208, Level 16, State 6, Procedure sp_bt_annl_stmt_members_select,
Line 1 [Batch Start Line 0] Invalid object name
'dbo.sp_bt_annl_stmt_members_select'.
CREATE PROCEDURE dbo.sp_bt_annl_stmt_members_select
AS
SELECT * FROM sysusers
Commands completed successfully.
Running the CREATE OR ALTER again works
CREATE OR ALTER PROCEDURE dbo.sp_bt_annl_stmt_members_select
AS
SELECT * FROM sysusers
Commands completed successfully.

DB2 stored procedure for clearing the database can't be found

I'm trying to create a DB2 stored procedure that will clear all the data tables and reset the indexes to 0. The creating of the procedure is pretty straightforward, but the issue is that DB2 immediately forgets it exists. What am I doing wrong?
Create a simple script:
create procedure CLEARTABLES()
language sql
BEGIN
commit;
truncate TABLE1 immediate;
truncate TABLE2 immediate;
truncate TABLE3 immediate;
END;
Make sure we can execute it:
GRANT EXECUTE ON PROCEDURE CLEARTABLES TO PUBLIC;
And here is where it all breaks down with No authorized routine named "CLEARTABLES" of type "PROCEDURE" having compatible arguments was found.. SQLCODE=-440, SQLSTATE=42884, DRIVER=4.26.14
CALL CLEARTABLES;
I've also tried execute, but this does not appear to do anything.
EXECUTE CLEARTABLES;
And to prove it exists:
SELECT * FROM SYSIBM.SYSROUTINES s
WHERE s.ROUTINETYPE = 'P' AND s.ROUTINENAME = 'CLEARTABLES'
I feel like I'm missing very obvious here so I've tried a lot of small things like parentheses, no parentheses, lower/upper case etc. I'm using DBeaver and I can see the procedure under Application Objects > Procedures named CLEARTABLES in all caps no parameters, yet DB2 somehow can't find it with the way I'm calling for it.

Creating table in Firebird script causes "unsuccessful metadata update" with deadlock

I have the following script that I run using "isql -i scriptfile.sql":
CONNECT C:\Databasefile.fdb USER user PASSWORD password;
SET TERM !! ;
EXECUTE BLOCK AS BEGIN
IF (EXISTS(SELECT 1 FROM rdb$relations WHERE rdb$relation_name = 'MYTABLE')) THEN
EXECUTE STATEMENT 'DROP TABLE MYTABLE;';
END!!
SET TERM ; !!
CREATE TABLE MYTABLE
(
MYCOLUMN VARCHAR(14) NOT NULL
);
The very first time I run this (when the table does not already exist) the table is created as expected.
If I run the script again I get the following error:
Statement failed, SQLCODE = -607
unsuccessful metadata update
-STORE RDB$RELATIONS failed
-deadlock
After line 8 in file d:\myscript.sql
When the script exits, MYTABLE has been deleted and can no longer be found in the database.
If I run the script a third time the table is once again created and no errors are thrown.
Why can't the script both delete and then recreate a table?
DDL from PSQL is not allowed, using EXECUTE STATEMENT it is not directly forbidden, and usually possible, but still not wise exactly because of these kinds of problems. I am not exactly sure about the reasons, but part of it have to do with how DDL changes are applied in Firebird; the use of execute statement adds additional locks iirc which conflict with a subsequent DDL for the same table name.
Instead of dropping and creating this way, you should use the DDL statement RECREATE TABLE instead.
Note that the word deadlock in this error is actually a bit of a misnomer (there is no real deadlock).

How to pass the CHAR as the input to the IDENTIFIED BY inside CREATE USER

I am attempting to create a database user from within a procedure in MariaDB 5.5.40
I can successfully do the following:
DROP PROCEDURE IF EXISTS testUserCreate;
DELIMITER //
CREATE PROCEDURE testUserCreate
(IN sDbUser CHAR(16), IN sDbPass CHAR(40))
BEGIN
CREATE USER sDbUser#'%';
END;
//
DELIMITER ;
So the procedure has no problems with using the parameterised user name, however, when i try to do the same with the password, like so:
DROP PROCEDURE IF EXISTS testUserCreate;
DELIMITER //
CREATE PROCEDURE testUserCreate
(IN sDbUser CHAR(16), IN sDbPass CHAR(40))
BEGIN
CREATE USER sDbUser#'%' IDENTIFIED BY PASSWORD PASSWORD(sDbPass);
END;
//
DELIMITER ;
I get the error:
ERROR 1064 (42000) at line 3: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'PASSWORD(sDbPass);
Yes, i have tried to change it to IDENTIFIED BY sDbPass and other variations i could think of.
The GRANT generates the exact same error if i attempt to add IDENTIFIED BY with the variable in it.
The question is: Is it possible, and if so how, to pass the char procedure variable into the IDENTIFIED BY clause inside the CREATE USER.
Ok, i guess that for whatever reason it's impossible. If somebody else will be looking for it, you will have to manually edit the mysql.user (and maybe mysql.db) table:
DROP PROCEDURE IF EXISTS testUserCreate;
DELIMITER //
CREATE PROCEDURE testUserCreate
(IN sDbUser CHAR(16), IN sDbPass CHAR(40))
BEGIN
INSERT INTO mysql.user (Host, User, Password) VALUES('%', sDbUser, PASSWORD(sDbPass));
FLUSH PRIVILEGES;
END;
//
DELIMITER ;