.sql database import not working. (stored procedure error) - mariadb

I am new to MySQL.
I want to import the database from .sql file.
Tables are imported successfully.
but it gives the below error regarding procedures :
CREATE DEFINER=`dev`#`%` PROCEDURE `sp_PlaceBet`(
IN `pLogInId` INT,
IN `pUserId` INT,
IN `pParantId` INT,
IN `pMatchId` INT,
IN `pSelectionId` INT,
IN `pStack` INT,
IN `pMarketId` VARCHAR(100),
IN `pselectionName` VARCHAR(100),
IN `pMstDate` DATETIME,
IN `pOdds` DECIMAL(10, 2),
IN `pP_L` DECIMAL(10, 2),
IN `pisBack` INT,
IN `pIsMatched` INT,
IN `pNarration` VARCHAR(200),
IN `pdeviceInfo` VARCHAR(100),
IN `pIP_ADDESSS` VARCHAR(100),
IN `pInPlayStack` INT,
IN `pIsApp` INT,
IN `pType` VARCHAR(100)
)
BEGIN
DECLARE LID INTEGER;
DECLARE lCtr integer;
DECLARE resultV INT;
DECLARE retMess VARCHAR(500);
DECLARE checkBal decimal(50, 2);
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
set resultV = -1;
GET STACKED DIAGNOSTICS CONDITION 1 #sqlstate = RETURNED_SQLSTATE, #errno = MYSQL_ERRNO, #text = MESSAGE_TEXT;
SET retMess = CONCAT("ERROR ", #errno, " (", #sqlstate, "): ", #text);
ROLLBACK;
[...]
MySQL said: Documentation
#1064 - 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 'STACKED DIAGNOSTICS CONDITION 1 #sqlstate = RETURNED_SQLSTATE, #errno = MYSQL...' at line 31
Please help me to solve this error.
Thanks!

The problem is that you are using mariadb, not mysql. If you check out the error message, it tells you to fefer to the mariadb manual.
Mariadb's get diagnostics statement does not have stacked option, so you must remove it if you want to use the code in a mariadb environment or you need to migrate to a proper mysql server.

Related

MariaDB create stored procedure syntax error

I feel like such a noob for asking this, but I can't for the life of me figure this one out. I'm trying to create a stored procedure here:
create or replace procedure add_cart(#user_id int, #product_id int, #quantity int)
begin
declare cart_id int;
start transaction;
select id into cart_id from carts where user_id = #user_id;
if cart_id is null then
insert into carts (user_id, updated_at, inserted_at) values (#user_id, now(), now());
select id into cart_id from carts where user_id = #user_id;
end if;
insert into cart_products (cart_id, product_id, quantity) values (cart_id, #product_id, #quantity);
commit;
end
But I keep getting this SyntaxError:
[2022-06-14 10:29:29] [42000][1064] (conn=12) 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 '#user_id int, #product_id int, #quantity int)
[2022-06-14 10:29:29] [42000][1064] 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 '#user_id int, #product_id int, #quantity int)
[2022-06-14 10:29:29] begin
[2022-06-14 10:29:29] declare cart_id int;
[2022-06-14 10:29:29] ...' at line 1
MariaDB version 10.6.0 if that's relevant.
Thanks :)
Nvm, got it. It was the # signs :)

Does FreeTDS ODBC + pyodbc support table-valued parameters (TVPs)?

I'm working on unix/rhel7 system. I have installed require drivers for FreeTDS, unixODBC and pyodbc.Other query is working fine but when I'm trying execute stored proc with TVP (table valued parameter), its giving me error. Is there any way to connect SQL Server using windows service account from python?
Example:
import pyodbc;
cnxn = pyodbc.connect('DRIVER=FreeTDS;SERVER=SERVERNAME;PORT=1234;UID=USERNAME;PWD=PASSWORD;DATABASE=DBNAME')
cnxn.cursor()
param_array = []
for i in range(3):
param_array.append(['abc', 'adi', '/somepath/', '2021-01-04', 'NEW'])
result_array = cursor.execute("EXEC abc.stored_proc_name ?", [param_array]).fetchall()
cursor.commit()
cnxn.close()
Error:
pyodbc.Error: ('HY004', '[HY004] [FreeTDS][SQL Server]Invalid data type (0) (SQLBindParameter)')
So Is there any other way to connect SQL service account from python which supports TVP? Or Is there any solution in above example?
FreeTDS ODBC does not directly support table-valued parameters (TVPs) as discussed here. However we can use a temporary table and an anonymous code block to work around the issue. For a user-defined table type
USE [myDb]
GO
/****** Object: UserDefinedTableType [dbo].[dboListInt] Script Date: 2021-02-18 10:53:17 ******/
CREATE TYPE [dbo].[dboListInt] AS TABLE(
[Id] [int] NOT NULL,
PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (IGNORE_DUP_KEY = OFF)
)
GO
and a stored procedure that accepts that table type
USE [myDb]
GO
/****** Object: StoredProcedure [dbo].[dboPyOdbcTestTvp] Script Date: 2021-02-18 10:41:43 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[dboPyOdbcTestTvp](#tvp [dbo].dboListInt READONLY)
AS
BEGIN
SET NOCOUNT ON;
SELECT * FROM #tvp
END
we can call the stored procedure and retrieve the results like so:
import pyodbc
cnxn = pyodbc.connect(
"DRIVER=FreeTDS_1.2.18;"
"SERVER=192.168.0.179;"
"PORT=49242;"
"DATABASE=myDb;"
"UID=sa;PWD=_whatever_;"
)
crsr = cnxn.cursor()
crsr.execute("CREATE TABLE #tvp_data (Id int)")
tvp_data = [(123, ), (234, ), (345, )]
crsr.executemany(
"INSERT INTO #tvp_data (Id) VALUES (?)",
tvp_data
)
crsr.execute("""\
SET NOCOUNT ON;
DECLARE #tvp dbo.dboListInt;
INSERT INTO #tvp (Id)
SELECT Id FROM #tvp_data;
EXEC dbo.dboPyOdbcTestTvp #tvp;
""")
print(crsr.fetchall())
# [(123, ), (234, ), (345, )]

Recursive stored procedure in HSQLDB

is it possible to create recursive stored procedure in HSQLDB ?
I wrote the following one to update a record and recursively all the parent records:
CREATE PROCEDURE updateFolderTotals(IN p_id VARCHAR(32), IN p_size BIGINT, IN p_files INT, IN p_folders INT)
MODIFIES SQL DATA
BEGIN ATOMIC
DECLARE l_parentid VARCHAR(32);
UPDATE folders
SET tot_files = tot_files + p_files,
tot_size = tot_size + p_size ,
tot_folders = tot_folders + p_folders
WHERE id = p_id;
SELECT parentid INTO l_parentid FROM folders WHERE id = p_id;
IF (l_parentid IS NOT NULL) THEN
CALL updateFolderTotals(l_parentid,p_size,p_files,p_folders);
END IF;
END;
but I get the following error:
user lacks privilege or object not found: UPDATEFOLDERTOTALS / Error Code: -5501 / State: 42501
In HyperSQL User Guide I've found some info (see Recursive Routines in HyperSQL User Guide) but it seems it is supported for funtions only.
Thank you in advance for support.
You can create recursive procedures following the same guidelines. First create the procedure with a simple body that throws an exception. You need to specify the SPECIFIC name of the procedure:
CREATE PROCEDURE updateFolderTotals(IN p_id VARCHAR(32), IN p_size BIGINT, IN p_files INT, IN p_folders INT)
SPECIFIC updateFolderTotals_1 MODIFIES SQL DATA
SIGNAL SQLSTATE '45000'
Then alter the created procedure with the full body:
ALTER SPECIFIC ROUTINE updateFolderTotals_1
BEGIN ATOMIC
DECLARE l_parentid VARCHAR(32);
UPDATE folders
SET tot_files = tot_files + p_files,
tot_size = tot_size + p_size ,
tot_folders = tot_folders + p_folders
WHERE id = p_id;
SELECT parentid INTO l_parentid FROM folders WHERE id = p_id;
IF (l_parentid IS NOT NULL) THEN
CALL updateFolderTotals(l_parentid,p_size,p_files,p_folders);
END IF;
END;

Can I reuse an INPUT parameter within the stored procedure?

Using SQL Server 2012 within asp.net webforms application, built in VS2012 Express for Web...
In my stored procedure, I have an input parameter #UID_LOGIN AS INT. This value may be ZERO at the time of the call.
CREATE PROCEDURE [dbo].[uspUpdateFromDetailsView]
#UID_CONTACT INT,
#UID_LOGIN INT,
#UID_USER_TYPE INT, -- etc...not shown here...
When this value is ZERO, a new LOGIN record is created and the SCOPE_IDENTITY() is used to fetch the new UID_LOGIN value as follows:
-- Retain the key to the inserted-row.
SET #UID_LOGIN = SCOPE_IDENTITY();
Can I be assured from your answer that this new value of #UID_LOGIN remains local to the stored procedure and does NOT change the value of the parameter.
Thanks in advance... John
Yes, #UID_LOGIN will remain = SCOPE_IDENTITY() within the BATCH until you set it to something else. Each time the procedure is executed you will have to pass in a new #UID_LOGIN because you have not given it a default value in your declaration. i.e. CREATE PROCEDURE [dbo].[uspUpdateFromDetailsView] (#UID_LOGIN = NULL) AS...
You can test snippets like this.
-- Comment out the create procedure part
--CREATE PROCEDURE [dbo].[uspUpdateFromDetailsView]
--( #UID_CONTACT INT,
-- #UID_LOGIN INT,
-- #UID_USER_TYPE INT
--)
--declare your variables
declare #UID_CONTACT INT, #UID_LOGIN INT, #UID_USER_TYPE INT
--set your variable
SET #UID_LOGIN = SCOPE_IDENTITY()
--do some stuff
INSERT INTO TableA (LOGIN) VALUES #UID_LOGIN
--check variable
SELECT #UID_LOGIN

RODBC command 'sqlQuery' has problems with table variables in t-SQL

I am using the RODBC package which I am applying on a Microsoft SQL Server 2012.
Now I have discovered a phenomenon that puzzles me.
If I run the following query with the RODBC command sqlQuery, then, in R, I will get back an empty data frame with the columns Country, CID, PriceID and WindID.
DECLARE #tbl_IDs TABLE
(
Country nvarchar(30),
CID nvarchar(5),
PriceID int,
WindID int
)
SELECT * FROM #tbl_Ids
So far, everything is fine.
However, if I try to write a record to the table variable and execute
DECLARE #tbl_IDs TABLE
(
Country nvarchar(30),
CID nvarchar(5),
PriceID int,
WindID int
)
INSERT INTO #tbl_IDs
VALUES
('Germany', 'DE', 112000001, 256000002);
SELECT * FROM #tbl_Ids
Then, in R, the result will be an empty character instead of a dataframe with one record. Still the same query works perfectly with SQL Server Management Studio.
Also, we have traced the behaviour of the DB Server while the R-Query is executed and it seems the server handles it perfectly. It seems that the RODBC interface has a problem to return the result to the R console.
Does anybody have an idea how this issue can be resolved?
Try toggling NOCOUNT as below:
old_qry <- "
DECLARE #tbl_IDs TABLE
(
Country nvarchar(30),
CID nvarchar(5),
PriceID int,
WindID int
)
INSERT INTO #tbl_IDs
VALUES
('Germany', 'DE', 112000001, 256000002);
SELECT * FROM #tbl_Ids
"
##
new_qry <- "
SET NOCOUNT ON;
DECLARE #tbl_IDs TABLE
(
Country nvarchar(30),
CID nvarchar(5),
PriceID int,
WindID int
);
INSERT INTO #tbl_IDs
VALUES
('Germany', 'DE', 112000001, 256000002);
SET NOCOUNT OFF;
SELECT * FROM #tbl_Ids
"
R> sqlQuery(tcon, gsub("\\n", " ", old_qry))
#character(0)
R> sqlQuery(tcon, gsub("\\n", " ", new_qry))
# Country CID PriceID WindID
#1 Germany DE 112000001 256000002
Basically you want to SET NOCOUNT ON at the beginning of your code, and SET NOCOUNT OFF just before the final SELECT statement.
Since database server handles query correctly, save the multiple line action TSQL query as a SQL Server Stored Procedure and have R call it retrieving the resultset.
Do note you can even pass parameters in the EXEC sp line from R to MSSQL. Also as mentioned, include the SET NOCOUNT ON declaration in the query to avoid undesired result character(0):
library("RODBC");
conn <- odbcConnect("DSN Name",uid="***",pwd="***"); # WITH DSN
#conn <-odbcDriverConnect('driver={SQL Server};server=servername;database=databasename;
#trusted_connection=yes;UID=username; PWD=password') # WITH DRIVER
df<-sqlQuery(conn, "EXEC dbo.StoredProcName");

Resources