MySql executing Set and Concat statements in VB.net - mysql

I am trying to get some values - columns as rows and viceversa - from MySQL to show on a DataGridView. I have this code, that should be run in MySQL-
SET #header = CONCAT('SELECT \'sl\', ',
(SELECT GROUP_CONCAT(CONCAT(' \'', sl, '\'')) FROM cars where sl=1),
' LIMIT 0, 0');
SET #a = -1;
SET #line1 = CONCAT(
'SELECT \'Plate\',',
(
SELECT GROUP_CONCAT(
CONCAT(' (SELECT Plate FROM cars LIMIT ',
#a:=#a+1,
', 1)')
)
FROM cars where sl=1
));
SET #a := -1;
SET #line2 = CONCAT(
'SELECT \'Brand\',',
(
SELECT GROUP_CONCAT(
CONCAT(' (SELECT Brand FROM cars LIMIT ',
#a:=#a+1,
', 1)')
)
FROM cars where sl=1
));
SET #query = CONCAT('(',
#header,
') UNION (',
#line1,
') UNION (',
#line2,
')'
);
PREPARE my_query FROM #query;
EXECUTE my_query;
Now when I try to run this via the ExecuteNonQuery command by saving all this code in a string, I get a MySQLException error- Fatal error encountered during command execution.
I have tried to split the code into separate strings, but the same error popped. Also tried to increase the CommandTimeout, but nothing worked.
Is there any special way to run these statements? Or is there any problem with the code? Please note that this runs effectively without any error on the command line client.
PS: The code is used from Q# 3288014 - Thanks to Anax
EDIT:
I found a work around to the same thing, but all done in VB.
Dim sa() As String = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
Dim sa2() As String = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
connect()
Dim reader As MySqlDataReader
execstr = "describe cars"
Dim cmd As New MySqlCommand(execstr, connection)
reader = cmd.ExecuteReader()
Dim i As Integer = 0
While reader.Read
sa(i) = reader.GetString(0)
i = i + 1
End While
reader.Close()
connection.Close()
connect()
execstr = "select*from cars where sl=1;"
Dim cmd2 As New MySqlCommand(execstr, connection)
reader = cmd2.ExecuteReader()
While reader.Read
For i1 As Integer = 0 To sa.Length - 1
sa2(i1) = reader.GetString(i1)
Next
End While
reader.Close()
connection.Close()
reader.Close()
connection.Close()
Dim t As New DataTable
t.Columns.Add(sa(0))
t.Columns.Add(sa2(0))
For y As Integer = 1 To sa.Length - 1
t.Rows.Add(sa(y), sa2(y))
Next
DataGridView1.DataSource = t
Funny to find that what all can be done in a string in MySQL, takes so much code in VB.

You can't do that in a single or series of ExecuteNonQuery command(s). This example was showing the code you would put in a stored procedure on mysql. The you call the stored procedure using a DataAdapter or DataReader.

Related

Executing SQL with parameters in SSIS

How do I execute the SQL script below a SSIS project? I've tried setting up parameters & variables; however.... nothing I do seems to pass the parameters via SSIS
declare #businessunit varchar(255) = 'Test'
declare #advisor varchar(255) = 'Smith'
declare #iuid int =
(
select U.[iuid]
from U
inner join [dbo].A on u.[ipartyid] = A.[iuserid]
inner join [dbo].B on A.[ibusinessunitid] = B.[ipartyid]
inner join [dbo].C on u.[ipartyid] = C.[ipartyid]
inner join [dbo].D on C.[ipartyid] = D.[ipartyid]
where 1 = 1
and B.[name] = #businessunit
and D.[lastname] = #advisor
)
select HHName
,HHID = h.ihhid
,FNAME =
case
when charindex(',', h.vhhname) > 0 and trim(substring(h.vhhname, patindex('% i%', h.vhhname), len(h.vhhname))) in ('i', 'ii', 'iii')
then concat(dbo.Propercase(concat(trim(substring(trim(substring(h.vhhname, charindex(' ', h.vhhname), len(h.vhhname))), 1, charindex(' ', trim(substring(h.vhhname, charindex(' ', h.vhhname), len(h.vhhname)))))), ' ', trim(substring(h.vhhname, 1, (charindex(',', h.vhhname) - 1))))), UPPER(substring(h.vhhname, patindex('% i%', h.vhhname), len(h.vhhname))))
when charindex(',', h.vhhname) > 0 and nullif(h.vdescr, '') is null
then dbo.Propercase(replace(replace(concat(trim(substring(h.vhhname, (charindex(',', h.vhhname) + 1), len(h.vhhname))), ' ', trim(substring(h.vhhname, 1, (charindex(',', h.vhhname) - 1)))), '+', '&'), ' and ', ' & '))
else dbo.Propercase(replace(isnull(nullif(h.vdescr, ''), h.vhhname), ' and ', ' & '))
end
,RepNo = h.planid
from [dbo].[HH] h
inner join
(
select u.[usertype]
,a.[user_planid]
from [dbo].users u
inner join [dbo].user_access a on u.iuid = a.iuid
where 1 = 1
and u.[usertype] <> 'e'
and u.iuid = #iuid
group by u.[usertype],a.[user_planid]
) p
on h.[planid] = p.[user_planid]
I'm going to assume you already have two SSIS variables that correspond to #businessunit and #advisor and they are being populated with the correct values already.
You can use an Execute SQL Task with parameter mapping to run your query. First thing you want to do is open the task editor, and configure your db connection. Next, hit the three dots next to SQLStatement to pull up the query editor window. Now you can start transposing your query, with a few modifications. I find that the Execute SQL Task works best when you separate variable declaration and assignment statements. You can use the following as your query text:
declare #businessunit varchar(255)
declare #advisor varchar(255)
declare #iuid int
SET #businessunit = ?
SET #advisor = ?
SET #iuid =
(
select U.[iuid]
from U
inner join [dbo].A on u.[ipartyid] = A.[iuserid]
inner join [dbo].B on A.[ibusinessunitid] = B.[ipartyid]
inner join [dbo].C on u.[ipartyid] = C.[ipartyid]
inner join [dbo].D on C.[ipartyid] = D.[ipartyid]
where 1 = 1
and B.[name] = #businessunit
and D.[lastname] = #advisor
)
select HHName
,HHID = h.ihhid
,FNAME =
case
when charindex(',', h.vhhname) > 0 and trim(substring(h.vhhname, patindex('% i%', h.vhhname), len(h.vhhname))) in ('i', 'ii', 'iii')
then concat(dbo.Propercase(concat(trim(substring(trim(substring(h.vhhname, charindex(' ', h.vhhname), len(h.vhhname))), 1, charindex(' ', trim(substring(h.vhhname, charindex(' ', h.vhhname), len(h.vhhname)))))), ' ', trim(substring(h.vhhname, 1, (charindex(',', h.vhhname) - 1))))), UPPER(substring(h.vhhname, patindex('% i%', h.vhhname), len(h.vhhname))))
when charindex(',', h.vhhname) > 0 and nullif(h.vdescr, '') is null
then dbo.Propercase(replace(replace(concat(trim(substring(h.vhhname, (charindex(',', h.vhhname) + 1), len(h.vhhname))), ' ', trim(substring(h.vhhname, 1, (charindex(',', h.vhhname) - 1)))), '+', '&'), ' and ', ' & '))
else dbo.Propercase(replace(isnull(nullif(h.vdescr, ''), h.vhhname), ' and ', ' & '))
end
,RepNo = h.planid
from [dbo].[HH] h
inner join
(
select u.[usertype]
,a.[user_planid]
from [dbo].users u
inner join [dbo].user_access a on u.iuid = a.iuid
where 1 = 1
and u.[usertype] <> 'e'
and u.iuid = #iuid
group by u.[usertype],a.[user_planid]
) p
on h.[planid] = p.[user_planid]
Hit OK in the query editor window.
The ? in the SET statements tell the task to pull the values from the Parameter Mapping. So now let's configure the parameter mappings.
In the left pane of the Execute SQL Task Editor, click on Parameter Mapping. If your db connection is OLE or EXCEL, then the Parameter Name will start with 0 and increment by one for each additional parameter. If it's an ODBC connection, you'll start with 1 instead. The parameter names match up with the ordinal position of the ?. So in our example here, #businessunit would be the first parameter mapped and #advisor would be the second. Now you're going to add two parameters. Hit the Add button, then change the Variable Name to your first SSIS variable. Leave Direction set to Input, change Data Type to VARCHAR, set the Parameter Name, then set the Parameter Size to 255. Repeat for the second variable. Your paramter mappings should look something like this:
Make sure you hit OK to save all your changes.
For a script as long as this, one solution that may work for you depending on what you are trying to achieve is to use SSIS script tasks.
Script tasks allow you to use C# (Or Visual Basic) in order to execute SQL via the same System.Data.SqlClient class that you would normally use in other C# programs, such as a console or ASP.NET application.
For your SQL above, put it into a stored procedure, and then execute this stored procedure within the script task. You could then use SqlDataReader or SqlDataAdapter to then read and store the result into a model.
From there, you can choose to manipulate the data within the SSIS script task.
For Example:
SqlConnection connection = new Connection("connection string");
using(SqlCommand command = new SqlCommand("Trans-SQL or stored procedure name", connection)
{
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(/*Add your parameters...*/);
connection.Open()
SqlDataReader reader = command.ExecuteReader()
while (reader.Read())
{
//Use reader["name"] in here to read values from response into a model
}
}
Is a completely valid way of querying data within a SSIS task. If you would rather not deal with a Reader, you can use the SqlDataAdapter and use the Fill() method to store the result(s) in a dataset.
Overall, when dealing with complex data (and where efficiency isn't too much of a concern), I find that completing actions within SSIS script tasks that get triggered by the control logic is the easier way to use SSIS.
You may find this Integration Services Programming Overview documentation site useful as a reference for some of the things you can do with SSIS script tasks.
On a final note, please be aware that script tasks in SSIS do have some limitations, a key one is that there is generally worse support for newer C# features, that cause issues such as not being able to hit debug breakpoints.

How can I add a parameter for mysql variable?

I have query in mysql which contains one variable. The query is
SELECT
GROUP_CONCAT(
CONCAT(
' MAX(IF(Property = ''',
t.Property,
''', Value, NULL)) AS ',
t.Property
)
) INTO #PivotQuery
FROM
(SELECT
Property
FROM
ProductOld
GROUP BY
Property) t;
SET #PivotQuery = CONCAT('SELECT ProductID,', #PivotQuery, ' FROM ProductOld GROUP BY ProductID');
PREPARE statement FROM #PivotQuery;
EXECUTE statement;
DEALLOCATE PREPARE statement;
But, when I run using mysqlcommand in my vb.net application, it throws an error stating that Parameter #PivotQuery must be defined..
Exchange This Code With your Existing Code:
SET #PivotQuery = CONCAT('SELECT ProductID',#PivotQuery,'FROM ProductOld GROUP BY ProductID');
Private Function saveCustomer()
Dim command As MySqlCommand = Nothing
Dim query As String = "INSERT INTO contacts (first_name, surname, house_number, street, suburb, state, phone, mobile, work, email, notes) VALUES (#first_name, #surname, #housenumber, #street, #suburb, #state, #phone, #mobile, #work, #email, #notes)"
Try
If connection.State = ConnectionState.Closed Then
connection.Open()
End If
command = New MySqlCommand(query, connection)
command.Parameters.AddWithValue("#first_name", txtFirstName.Text)
command.Parameters.AddWithValue("#surname", txtSurname.Text)
command.Parameters.AddWithValue("#housenumber", txtHouseNo.Text)
command.Parameters.AddWithValue("#street", txtStreet.Text)
command.Parameters.AddWithValue("#suburb", txtSuburb.Text)
command.Parameters.AddWithValue("#state", cboState.Text)
command.Parameters.AddWithValue("#phone", txtPhone.Text)
command.Parameters.AddWithValue("#mobile", txtMobile.Text)
command.Parameters.AddWithValue("#work", txtWork.Text)
command.Parameters.AddWithValue("#email", txtEmail.Text)
command.Parameters.AddWithValue("#notes", txtNotes.Text)
command.ExecuteNonQuery()
MessageBox.Show("Contact Saved Sucessfully")
Return True
Catch ex As MySqlException
Return False
Finally
connection.Close()
command.Dispose()
End Try

Create duplicate row for each item in column containing delimited string

I have a table with a column that stores time blocks separated by semi-colons (;). I would like to create a row for each time block, for example, given
I'd like to create a row for each time block
Please let me know if this possible in Access.
Edit
I tried using this query
SELECT * INTO ImportedData
FROM (
SELECT [SourceData].[Time block], [SourceData].[Work History Id],[SourceData].[Operation Code]
FROM SourceData
WHERE InStr([SourceData].[Time block], ';') = 0
UNION ALL
SELECT Left([SourceData].[Time block], InStr([SourceData].[Time block], ';') - 1),[SourceData].[Work History Id], [SourceData].[Operation Code]
FROM SourceData
WHERE InStr([SourceData].[Time block], ';') > 0
UNION ALL
SELECT Mid([SourceData].[Time block], InStr([SourceData].[Time block], ';') + 1), [SourceData].[Work History Id], [SourceData].[Operation Code]
FROM SourceData
WHERE InStr([SourceData].[Time block], ';') > 0) AS CleanedUp;
and I also tried this VBA code with no luck.
Public Sub addToTable()
Dim rstObj As DAO.Recordset, dbObj As DAO.Database
Dim InsertSQL As String
Set dbObj = CurrentDb()
Set rstObj = dbObj.OpenRecordset("Query1")
Do While Not rstObj.EOF
Dim memArr() As String
memArr = Split(rstObj.Fields("Time block"), ",")
For i = 0 To UBound(memArr)
InsertSQL = "SELECT*INTO ImportedData(Time block, Work History ID) VALUES(""" & rstObj.Fields("Time block") & """, """ & memArr(i) & """)"
DoCmd.RunSQL (InsertSQL)
Next
rstObj.MoveNext
Loop
End Sub
Found the answer here [enter link description here][1]
[1]: http://www.access-programmers.co.uk/forums/showthread.php?t=239727 for anyone that may b have the same requirements, i would hope people would actually help instead of just marking down answers or correcting the way the question is asked.

Format the SQL query to a variable

DECLARE #sql nvarchar(4000)
SET #sql='SELECT DISTINCT
WS.SIMNumber,
SMTP.SMTPMappingId,
CONVERT(VARCHAR(11),WS.ExpiryDate,106) as ExpiryDate,
CASE
WHEN BES.DisplayName IS NOT NULL THEN BES.DisplayName+'#'+SMTP.DomainName
ELSE
CASE WHEN BES.PIN IS NOT NULL THEN BES.PIN+'#'+SMTP.DomainName
ELSE '' END END AS EmailId,
CASE
WHEN (SELECT COUNT(*) FROM dbo.ExpiringEmailSimCardSent WHERE SimNumber=WS.SIMNumber AND ExpiryDate=WS.ExpiryDate)>0
THEN CONVERT(BIT,1)
ELSE CONVERT(BIT,0)
END AS IsEMailSent
FROM
WEBSERVICE_CACHE AS WS
LEFT OUTER JOIN
BES_SERVER_CACHE AS BES ON WS.SIMNumber = LEFT(BES.ICCID,19)
LEFT OUTER JOIN
BES_SMTP_Mapping AS SMTP ON BES.BESSqlServer = SMTP.BesServer
WHERE
CONVERT(DATETIME, GETDATE(), 109) > CONVERT(DATETIME, WS.ExpiryDate, 109)'
EXECUTE sp_executesql #sql
I have this SQL query want to convert it into a `nvarchar` variable because of # and '' . I am getting some errors
I am getting this errorMsg 102, Level 15, State 1, Line 9
Incorrect syntax near '#'.
If I rectify that it comes for another at # and ' '
You have to 'escape' your quotes:
This:
BES.PIN+'#'+SMTP.DomainName
Should be something like this:
BES.PIN+'''#'''+SMTP.DomainNam
experiment....

recordset.sort invalid row handle

I have a MySQL stored procedure generating a resultset. The query uses GROUP_CONCAT to select rows as columns.
SQL Code snippet
SELECT CONCAT(
' SELECT MDE_ID, MDE_CreatedOn, MDE_LastEditedOn '
, GROUP_CONCAT(CONCAT(
' ,t', MDF_ID, '.MDEMDF_Value AS `', REPLACE(MDF_Label, '`', '``'), '`'
) SEPARATOR ' ')
Following, I want to sort the recordset on a column.
SQL = "CALL moduleentry_select(" & prjid & ",0,26,0)"
set rs = Server.CreateObject("ADODB.Recordset")
rs.CursorLocation = 3
rs.LockType = 3
rs.Open SQL, Conn
rs.Sort = "volgnummer"
I have verified and the column is in the recordset.
I get the following error:
Microsoft Cursor Engine error '80040e04'
Row handle is invalid.
default.asp, line 176
Line 176 is rs.Sort = "volgnummer"
edit
The column 'Volgnummer' doesn't actually exist in the database. It is selected dynamically via a pivoting principle, using GROUP_CONCAT. Referring to this SA answer: joined table rows into columns with column titles from original rows