Migrating MySQL procedure to SQL Server - sql-server

So I'm migrating data from a MySQL (MariaDB) to a SQL Server 2019, and all tables migrated fine, but the stored procedures didn't, and I would like to know what causes this error, since I've never used SQL Server only MySQL.
My ERROR log form SQL Server Migration Assistant for MySQL
Starting Phase #1
Loading to database new procedure SwMetrics.testreportingdebug.AddTestCaseRequirement ...
... sql execution failed
Loading to database new procedure SwMetrics.testreportingdebug.AddTestResultRequirement ...
... sql execution failed
Loading to database new procedure SwMetrics.testreportingdebug.BeginTestResults ...
... sql execution failed
Loading to database new procedure SwMetrics.testreportingdebug.BeginTestRun ...
... sql execution failed
Loading to database new procedure SwMetrics.testreportingdebug.BeginTestRunWithTestJob ...
... sql execution failed
Loading to database new procedure SwMetrics.testreportingdebug.CreateJiraLink ...
... sql execution failed
Loading to database new procedure SwMetrics.testreportingdebug.CreateTarget ...
... sql execution failed
Loading to database new procedure SwMetrics.testreportingdebug.CreateTestCase ...
... sql execution failed
Loading to database new procedure SwMetrics.testreportingdebug.CreateTestJob ...
... sql execution failed
Loading to database new procedure SwMetrics.testreportingdebug.CreateTestResultsJiraLink ...
... sql execution failed
Loading to database new procedure SwMetrics.testreportingdebug.CreateTestSuite ...
... sql execution failed
Loading to database new procedure SwMetrics.testreportingdebug.CreateTestSuiteCaseLink ...
... sql execution failed
Loading to database new procedure SwMetrics.testreportingdebug.CreateTestSuiteCollection ...
... sql execution failed
Loading to database new procedure SwMetrics.testreportingdebug.CreateTestSuiteCollectionLink ...
... sql execution failed
Loading to database new procedure SwMetrics.testreportingdebug.CreateVersion ...
... sql execution failed
Loading to database new procedure SwMetrics.testreportingdebug.EndTestJob ...
... sql execution failed
Loading to database new procedure SwMetrics.testreportingdebug.EndTestResults ...
... sql execution failed
Loading to database new procedure SwMetrics.testreportingdebug.EndTestRun ...
... sql execution failed
Loading to database new function SwMetrics.testreportingdebug.IsTemporaryName ...
... sql execution failed
Loading to database new procedure SwMetrics.testreportingdebug.SetStatusName ...
... sql execution failed
Loading to database new procedure SwMetrics.testreportingdebug.SetTestJobFinished ...
... sql execution failed
Errors: DEFAULT or NULL are not allowed as explicit identity values.
Synchronization error: DEFAULT or NULL are not allowed as explicit identity values. On: SwMetrics.testreportingdebug.AddTestCaseRequirement
Errors: DEFAULT or NULL are not allowed as explicit identity values.
Synchronization error: DEFAULT or NULL are not allowed as explicit identity values. On: SwMetrics.testreportingdebug.AddTestResultRequirement
Errors: Incorrect syntax near '`'.
Incorrect syntax near '`'.
Incorrect syntax near '`'.
An object or column name is missing or empty. For SELECT INTO statements, verify each column has a name. For other statements, look for empty alias names. Aliases defined as "" or [] are not allowed. Change the alias to a valid name.
Synchronization error: Incorrect syntax near '`'.
Incorrect syntax near '`'.
Incorrect syntax near '`'.
An object or column name is missing or empty. For SELECT INTO statements, verify each column has a name. For other statements, look for empty alias names. Aliases defined as "" or [] are not allowed. Change the alias to a valid name. On: SwMetrics.testreportingdebug.BeginTestResults
Errors: DEFAULT or NULL are not allowed as explicit identity values.
Synchronization error: DEFAULT or NULL are not allowed as explicit identity values. On: SwMetrics.testreportingdebug.BeginTestRun
Errors: DEFAULT or NULL are not allowed as explicit identity values.
Synchronization error: DEFAULT or NULL are not allowed as explicit identity values. On: SwMetrics.testreportingdebug.BeginTestRunWithTestJob
Errors: DEFAULT or NULL are not allowed as explicit identity values.
Synchronization error: DEFAULT or NULL are not allowed as explicit identity values. On: SwMetrics.testreportingdebug.CreateJiraLink
Errors: DEFAULT or NULL are not allowed as explicit identity values.
Synchronization error: DEFAULT or NULL are not allowed as explicit identity values. On: SwMetrics.testreportingdebug.CreateTarget
Errors: DEFAULT or NULL are not allowed as explicit identity values.
Synchronization error: DEFAULT or NULL are not allowed as explicit identity values. On: SwMetrics.testreportingdebug.CreateTestCase
Errors: DEFAULT or NULL are not allowed as explicit identity values.
Synchronization error: DEFAULT or NULL are not allowed as explicit identity values. On: SwMetrics.testreportingdebug.CreateTestJob
Errors: DEFAULT or NULL are not allowed as explicit identity values.
Synchronization error: DEFAULT or NULL are not allowed as explicit identity values. On: SwMetrics.testreportingdebug.CreateTestResultsJiraLink
Errors: DEFAULT or NULL are not allowed as explicit identity values.
Synchronization error: DEFAULT or NULL are not allowed as explicit identity values. On: SwMetrics.testreportingdebug.CreateTestSuite
Errors: DEFAULT or NULL are not allowed as explicit identity values.
Synchronization error: DEFAULT or NULL are not allowed as explicit identity values. On: SwMetrics.testreportingdebug.CreateTestSuiteCaseLink
Errors: DEFAULT or NULL are not allowed as explicit identity values.
Synchronization error: DEFAULT or NULL are not allowed as explicit identity values. On: SwMetrics.testreportingdebug.CreateTestSuiteCollection
Errors: DEFAULT or NULL are not allowed as explicit identity values.
Synchronization error: DEFAULT or NULL are not allowed as explicit identity values. On: SwMetrics.testreportingdebug.CreateTestSuiteCollectionLink
Errors: DEFAULT or NULL are not allowed as explicit identity values.
Synchronization error: DEFAULT or NULL are not allowed as explicit identity values. On: SwMetrics.testreportingdebug.CreateVersion
Errors: Incorrect syntax near '`'.
Synchronization error: Incorrect syntax near '`'. On: SwMetrics.testreportingdebug.EndTestJob
Errors: Incorrect syntax near '`'.
Synchronization error: Incorrect syntax near '`'. On: SwMetrics.testreportingdebug.EndTestResults
Errors: Incorrect syntax near '`'.
Synchronization error: Incorrect syntax near '`'. On: SwMetrics.testreportingdebug.EndTestRun
Errors: Invalid column name '__'.
Invalid column name '__'.
Synchronization error: Invalid column name '__'.
Invalid column name '__'. On: SwMetrics.testreportingdebug.IsTemporaryName
Errors: DEFAULT or NULL are not allowed as explicit identity values.
Synchronization error: DEFAULT or NULL are not allowed as explicit identity values. On: SwMetrics.testreportingdebug.SetStatusName
Errors: Incorrect syntax near '`'.
Synchronization error: Incorrect syntax near '`'. On: SwMetrics.testreportingdebug.SetTestJobFinished
Synchronization operation is complete.
Error 1
An example of one of the failing MySQL stored procedures BeginTestRun
CREATE DEFINER=`root`#`localhost` PROCEDURE `BeginTestRun`(StartTime DATETIME, TestJobId INT)
BEGIN
INSERT INTO TestRuns (`id`,`StartTime`, `TestJobId`)
VALUES (NULL,StartTime,TestJobId);
SELECT LAST_INSERT_ID() AS LastInsertId;
END
The above one had this error:
Errors: DEFAULT or NULL are not allowed as explicit identity values.
What should I write instead of NULL? and why isn't this allowed?
Error 2
Another one EndTestRun
CREATE DEFINER=`root`#`localhost` PROCEDURE `EndTestRun`(TestRunId INT, EndTime DATETIME)
BEGIN
UPDATE TestRuns
SET `EndTime` = EndTime
WHERE ID = TestRunId;
SELECT LAST_INSERT_ID() AS LastInsertId;
END
Had this error
Synchronization error: Incorrect syntax near '`'. On: SwMetrics.testreportingdebug.EndTestRun
Errors: Invalid column name '__'.
I don't really see where __ should be?
Error 3
And another different one is CreateVersion
CREATE DEFINER=`edmetrics`#`%` PROCEDURE `CreateVersion`(varName varchar(100), Version varchar(100), TargetId INT)
BEGIN
INSERT INTO Versions(`id`,`Name`,`Version`,`TargetId`)
VALUES (NULL,varName,Version,TargetId);
SELECT LAST_INSERT_ID() AS LastInsertId;
END
With the error
Synchronization error: DEFAULT or NULL are not allowed as explicit identity values. On: SwMetrics.testreportingdebug.CreateVersion
Errors: Incorrect syntax near '`'.
Should ` just be removed, why isn't it allowed?

First SQL Server does not accepts accents (which are specific to MySQL) to delimits SQL identifiers (name of table, column, procedure... and so on). You must use SQL ISO standard double quote or specific SQL Server delimiter (square brackets) or nothing if your SQL identifier conforms to the standard. So :
CREATE DEFINER=`root`#`localhost` PROCEDURE `BeginTestRun` ...
Must be rewrite as :
CREATE DEFINER="root`#`localhost" PROCEDURE "BeginTestRun" ...
Or :
CREATE DEFINER=[root`#`localhost] PROCEDURE [BeginTestRun] ...
Second DEFINER is aspecific MySQL terms/object that ISO SQL Standard does not know, nor Microsoft SQL Server. The equivalent in the standard ISO SQL is the owner of the objects that is automatically associated to the SQL user that execute the CREATE statement. So :
CREATE DEFINER=`root`#`localhost` PROCEDURE `BeginTestRun` ...
Must be rewrite as :
CREATE PROCEDURE "BeginTestRun" ...
Third, every variables must be prefixed with a "#" (arobas / at sign). So :
CREATE DEFINER=`root`#`localhost` PROCEDURE `BeginTestRun`(StartTime DATETIME, TestJobId INT)
Must be rewrite :
CREATE PROCEDURE [BeginTestRun] (#StartTime DATETIME, #TestJobId INT)
Fourth, DATETIME is an obsolete datatype and it would be preferable to use DATETIME2. So
CREATE DEFINER=`root`#`localhost` PROCEDURE `BeginTestRun`(StartTime DATETIME, TestJobId INT)
Must be rewrite as :
CREATE PROCEDURE [BeginTestRun] (#StartTime DATETIME2, #TestJobId INT)
Fith, LAST_INSERT_ID() does not exists in SQL Server and must be replaced by SCOPE_IDENTITY(). So :
CREATE DEFINER=`root`#`localhost` PROCEDURE `BeginTestRun`(StartTime DATETIME, TestJobId INT)
BEGIN
INSERT INTO TestRuns (`id`,`StartTime`, `TestJobId`)
VALUES (NULL,StartTime,TestJobId);
SELECT LAST_INSERT_ID() AS LastInsertId;
END
Must be rewrite as :
CREATE PROCEDURE [BeginTestRun] (#StartTime DATETIME2, #TestJobId INT)
BEGIN
INSERT INTO TestRuns (id, StartTime, TestJobId)
VALUES (NULL, #StartTime, #TestJobId);
SELECT SCOPE_IDENTITY() AS LastInsertId;
END
Sixth, because SQL Server procedures are created by default in a debug mode, you must prefer to add the SET NOCOUNT ON statement to avoid untimely messages during operation. So :
CREATE DEFINER=`root`#`localhost` PROCEDURE `BeginTestRun`(StartTime DATETIME, TestJobId INT)
BEGIN
INSERT INTO TestRuns (`id`,`StartTime`, `TestJobId`)
VALUES (NULL,StartTime,TestJobId);
SELECT LAST_INSERT_ID() AS LastInsertId;
END
Must be rewrite as :
CREATE PROCEDURE [BeginTestRun] (#StartTime DATETIME2, #TestJobId INT)
BEGIN
SET NOCOUNT ON;
INSERT INTO TestRuns (id, StartTime, TestJobId)
VALUES (NULL, #StartTime, #TestJobId);
SELECT SCOPE_IDENTITY() AS LastInsertId;
END
Seventh, when your table as an IDENTITY column, by default you cannot INSERT any value inside. So, if your column id in the table TestRuns is an IDENTITY, you should not specify this column in the list of insert target columns. So :
CREATE DEFINER=`root`#`localhost` PROCEDURE `BeginTestRun`(StartTime DATETIME, TestJobId INT)
BEGIN
INSERT INTO TestRuns (`id`,`StartTime`, `TestJobId`)
VALUES (NULL,StartTime,TestJobId);
SELECT LAST_INSERT_ID() AS LastInsertId;
END
Must be rewrite as :
CREATE PROCEDURE [BeginTestRun] (#StartTime DATETIME2, #TestJobId INT)
BEGIN
SET NOCOUNT ON;
INSERT INTO TestRuns (StartTime, TestJobId)
VALUES (#StartTime, #TestJobId);
SELECT SCOPE_IDENTITY() AS LastInsertId;
END
Of course, the best way is to learn Transact SQL !

Errors: DEFAULT or NULL are not allowed as explicit identity values.
I imagine that the id column in this table is an identity, which means the following code should work.
CREATE PROCEDURE CreateVersion #varName varchar(100), #Version varchar(100), #TargetId INT
AS
BEGIN
INSERT INTO Versions(Name,Version,TargetId)
VALUES (#varName,#Version,#TargetId);
SELECT SCOPE_IDENTITY() AS LastInsertId;
END

Related

Cannot insert value NULL into column, but values in error message have nothing to do with my code

I have a VB.NET program that calls a stored procedure in SQL Server which inserts data into a table. Upon running this code, I get the following error message:
Msg 515, Level 16, State 2, Procedure uspAddSponsor, Line 19 [Batch Start Line 406]
Cannot insert the value NULL into column 'intGenderID', table 'dbSQL1.dbo.TGolfers'; column does not allow nulls. INSERT fails.
The problem is that neither intGenderID nor TGolfers are referenced in the stored procedure.
Here is my stored procedure code:
CREATE PROCEDURE uspAddSponsor
--#intGolferID AS INTEGER OUTPUT
#strFirstName AS VARCHAR(255),
#strLastName AS VARCHAR(255),
#strStreetAddress AS VARCHAR(255),
#strCity AS VARCHAR(255),
#strState AS VARCHAR(255),
#strZip AS VARCHAR(255),
#strPhoneNumber AS VARCHAR(255),
#strEmail AS VARCHAR(255)
AS
SET XACT_ABORT ON
BEGIN TRANSACTION
INSERT INTO TSponsors (strFirstName, strLastName, strStreetAddress, strCity, strState, strZip, strPhoneNumber, strEmail)
VALUES (#strFirstName, #strLastName, #strStreetAddress, #strCity, #strState, #strZip, #strPhoneNumber, #strEmail)
COMMIT TRANSACTION
GO
Here is the code used to call the stored procedure:
EXECUTE uspAddSponsor 'Joe', 'Johnson', '420 Main St', 'Ashton Park', 'IN', '46225', '5136656969', 'jjohnson#gmail.com'
Here's the sticky part. Running the INSERT statement by itself works with no problems. However, executing the stored procedure, which features the exact same INSERT statement, causes the error above. I truly have no idea what's going on.
There's no foreign key linking TGolfers and TSponsors. TSponsors doesn't even have an intGenderID column. I have no idea what could be causing this.
Thanks for any help!
This is what fixed the problem, although I'm not sure why the error occurred in the first place. I still have the DB script that I had used to create the db and everything in it, so I re-ran the script to reset the database, and the problem went away.

Issues when using SSIS Execute SQL Task to insert a row into SQL Server with multiple parameters

I am trying to use SSIS to insert a row with multiple parameters but I get this error :
[Execute SQL Task] Error: Executing the query "insert into ids (id,sqljobname,ojobname,ojobstartd..." failed with the following error: "The statement has been terminated.". Possible failure reasons: Problems with the query, "ResultSet" property not set correctly, parameters not set correctly, or connection not established correctly.
This is how I set up the Execute SQL Task:
insert into ids (id, sqljobname, ojobname, ojobstartdate)
values (?, ?, ?, ?)
Please let me know where I set it up wrong. I don't think the ParentJobStartDate is an issue because I set it up with string.
I am sorry guys, everything I did was correct. I just made a mistake when creating the table in sql server. I created the table like this:
create table ids
(id int,
sqljobname nvarchar(255),
ojobname nvarchar(255),
ojobstartdate nvarchar(255),
sqljobstartdate datetime )
So the columns will only have 1 for the size and make the insert failed. I have already fixed it.

Incorrect syntax near the keyword 'with' in stored procedure when using OPENJSON

Hi I created a stored procedure that uses OPEN JSON and insert data into a table.
The problem is when I run the stored procedure it shows an error.
I am using SQL server 2016 (SQl Server 13.0.4446.0). I am not getting the same issue when using using sql server 13.0.1742.0
CREATE PROCEDURE [dbo].Test2--'[{"FileId":1,"DataRow":"3000926900"}]'
(
#data varchar(max)
)
AS
BEGIN
create table #Temp
(
FileId bigint,
DataRow nvarchar(max),
DateLoaded DateTime
)
INSERT INTO [dbo].#Temp
SELECT * FROM OPENJSON(#data)
WITH (FileId bigint,
DataRow nvarchar(max),
DateLoaded DateTime)
select * from #temp
END
Error:
If this statement is a common table expression, an xmlnamespaces clause or a change tracking context clause, the previous statement must be terminated with a semicolon.
Check your database compatibility level. OPENJSON is new with SQL Server 2016, and if your compatibility level is set "SQL Server 2014 (120)" or less the OPENJSON function will not be correctly recognized or executed. See the MSDN docs at https://learn.microsoft.com/en-us/sql/t-sql/functions/openjson-transact-sql .

Use the result of a system stored procedure as a queryable table

Note: the highest linked question does not solve the problem for system stored procedures, but it's close. With help of the commenters, I came to a working answer.
Trying to use statements such as the following for sp_spaceused, throws an error
SELECT * INTO #tblOutput exec sp_spaceused 'Account'
SELECT * FROM #tblOutput
The errors:
Must specify table to select from.
and:
An object or column name is missing or empty. For SELECT INTO statements, verify each column has a name. For other statements, look for empty alias names. Aliases defined as "" or [] are not allowed. Change the alias to a valid name.
When I fully declare a table variable, it works as expected, so it seems to me that the stored procedure does return an actual table.
CREATE TABLE #tblOutput (
name NVARCHAR(128) NOT NULL,
rows CHAR(11) NOT NULL,
reserved VARCHAR(18) NOT NULL,
data VARCHAR(18) NOT NULL,
index_size VARCHAR(18) NOT NULL,
unused VARCHAR(18) NOT NULL)
INSERT INTO #tblOutput exec sp_spaceused 'Response'
SELECT * FROM #tblOutput
Why is it not possible to use a temp table or table variable with the result set of EXECUTE sp_xxx? Or: does a more compact expression exist than having to predefine the full table each time?
(incidentally, and off-topic, Googling for the exact term SELECT * INTO #tmp exec sp_spaceused at the time of writing, returned exactly one result)
TL;DR: use SET FMTONLY OFF with OPENQUERY, details below.
It appears that the link provided by Daniel E. is only part of the solution. For instance, if you try:
-- no need to use sp_addlinkedserver
-- must fully specify sp_, because default db is master
SELECT * FROM OPENQUERY(
[SERVERNAME\SQL2008],
'exec somedb.dbo.sp_spaceused ''Account''')
you will receive the following error:
The OLE DB provider "SQLNCLI10" for linked server "LOCALSERVER\SQL2008" supplied inconsistent metadata for a column. The name was changed at execution time.
I found the solution through this post, and then a blog-post on OPENQUERY, which in turn told me that until SQL2008, you need to use SET FMTONLY OFF. The final solution, which is essentially surprisingly simple (and easier to accomplish since there is no need to specify a loopback linked server), is this:
SELECT * FROM OPENQUERY(
[SERVERNAME\SQL2008],
'SET FMTONLY OFF
EXEC somedb.dbo.sp_spaceused ''Account''')
In addition, if you haven't set DATA-ACCESS, you may get the following error:
Server 'SERVERNAME\SQL2008' is not configured for DATA ACCESS.
This can be remedied by running the following command:
EXEC sp_serveroption 'SERVERNAME\SQL2008', 'DATA ACCESS', TRUE
We cannot SELECT from a stored procedure thats why SELECT * INTO ..Exec sp_ will not work.
To get the result set returned from a store procedure we can INSERT INTO a table.
SELECT INTO statement creates a table on fly and inserts data from the source table/View/Function. The only condition is source table should exist and you should be able to Select from it.
Sql Server doesn't allow you to use SELECT from sp_ therefore you can only use the INSERT INTO statement when executing a stored procedure this means at run time you can add the returned result set into a table and Select from that table at later stage.
INSERT INTO statement requires the destination table name, An existing table. Therefore whether you use a Temp Table, Table variable or Sql server persistent table you will need to create the table first and only they you can use the syntax
INSERT INTO #TempTable
EXECUTE sp_Proc
Using [YOUR DATABASE NAME]
CREATE TABLE [YOURTABLENAME]
(Database_Name Varchar(128),
DataBase_Size VarChar(128),
unallocated_Space Varchar(128),
reserved Varchar(128),
data Varchar(128),
index_size Varchar(128),
unused Varchar(128)
);
INSERT INTO dbo.[YOUR TABLE NAME]
(
Database_Name,
DataBase_Size,
unallocated_Space,
reserved,
data,
index_size,
unused
)
EXEC sp_spaceused #oneresultset = 1
--To get it to return it all as one data set add the nonresultset=1 at the end and viola good to go for writing to a table. :)

callablestatement.execute() returns an empty resultset if MS SQL preocedure contains CREATE TABLE statement

I use Callablestatement class execute() method to call MS SQL procedure.
I call MS SQL procedure which contains the following statement:
CREATE TABLE #PrevOver (ClCode char(6) NULL ,
ContrNum char(4) NULL ,
OverContr smallint NULL,
GenerNum tinyint NULL )
Table is used as a temporary data storage
If I drop the statement above and re-write procedure that way that it returns data with select statement only - everything works fine. The problem is that some procedures require "CREATE TABLE" statement.
I connect with "sa" permits, so it shouldn't be permission problem.
I use jtds
Thanks in advance.
Add the following parameters to procedure body:
*SET NOCOUNT ON
SET FMTONLY OFF*

Resources