recordset.sort invalid row handle - mysql

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

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.

MySql pivot table dynamic columns

I've got the following tables in my database:
this is the table km_kondomanager_millesimal_table_values
this is the table km_kondomanager_millesimal_table
The two tables are joined together by km_kondomanager_millesimal_table_value_table_id and km_kondomanager_millesimal_table_id
I've managed to creat a pivot table using the followinf query:
SELECT km_kondomanager_millesimal_table_value_building_id
,SUM(CASE WHEN km_kondomanager_millesimal_table_value_table_id = 9
THEN km_kondomanager_millesimal_table_millesimal_value END) tabella_gruppo_A
,SUM(CASE WHEN km_kondomanager_millesimal_table_value_table_id = 10
THEN km_kondomanager_millesimal_table_millesimal_value END) tabella_gruppo_B
FROM km_kondomanager_millesimal_table_values
WHERE km_kondomanager_millesimal_table_value_group_id = 15
GROUP BY km_kondomanager_millesimal_table_value_building_id
and this is how it looks like:
My problem is that I need to take the table name from km_kondomanager_millesimal_table and use it as column, these columns are not always the same as you can see in the immage there are other stored in the database. The query I've created requires to specify km_kondomanager_millesimal_table_value_table_id in the case and also to specify the column name in the example tabella_gruppo_A and tabella_gruppo_B. Can anyboby help me to achieve this? Also I need to convert the pit table to HTML table. Many thanks
I've managed to get it sorted using mysql stored procedure and this is the code:
BEGIN
SELECT
GROUP_CONCAT(
CONCAT("MAX(IF(km_kondomanager_millesimal_table_value_table_id='", km_kondomanager_millesimal_table_value_table_id, "',km_kondomanager_millesimal_table_millesimal_value ,NULL)) AS '", km_kondomanager_millesimal_table_name, "'"), "
"
)INTO #answers
FROM (
SELECT DISTINCT km_kondomanager_millesimal_table_value_table_id, km_kondomanager_millesimal_table_name FROM km_kondomanager_millesimal_table_values INNER JOIN km_kondomanager_millesimal_table
ON km_kondomanager_millesimal_table_values . km_kondomanager_millesimal_table_value_table_id = km_kondomanager_millesimal_table. km_kondomanager_millesimal_table_id WHERE km_kondomanager_millesimal_table_value_group_id = 13
) A;
SET #query :=
CONCAT(
'SELECT km_kondomanager_millesimal_table_value_building_id, ', #answers,
' FROM km_kondomanager_millesimal_table_values WHERE km_kondomanager_millesimal_table_value_group_id = 13 GROUP BY km_kondomanager_millesimal_table_value_building_id'
);
PREPARE statement FROM #query;
EXECUTE statement;
END

Add autoincrement to existing query (not table) in MS Access 2016

I have query in MS ACCESS 2016 that I need to add autonumber to. Basically, the query output results in one column of data and I want to add a new column to this output with numbers starting from 1 to whatever the row count of the query output will be. I dont want to create a new table from my query output though. Is there a way to do this in a query? I managed to add a new ID column that just has a scalar value, however what I need is auto increment here. Any thoughts?
SELECT qry.ColA, 1 AS ID
FROM qry;
Yes, use the RowNumber function from my article:
Sequential Rows in Microsoft Access
Full code at GitHub: VBA.RowNumbers
' Builds consecutive row numbers in a select, append, or create query
' with the option of a initial automatic reset.
' Optionally, a grouping key can be passed to reset the row count
' for every group key.
'
' Usage (typical select query):
' SELECT RowNumber(CStr([ID])) AS RowID, *
' FROM SomeTable
' WHERE (RowNumber(CStr([ID])) <> RowNumber("","",True));
'
' Usage (with group key):
' SELECT RowNumber(CStr([ID]), CStr[GroupID])) AS RowID, *
' FROM SomeTable
' WHERE (RowNumber(CStr([ID])) <> RowNumber("","",True));
'
' The Where statement resets the counter when the query is run
' and is needed for browsing a select query.
'
' Usage (typical append query, manual reset):
' 1. Reset counter manually:
' Call RowNumber(vbNullString, True)
' 2. Run query:
' INSERT INTO TempTable ( [RowID] )
' SELECT RowNumber(CStr([ID])) AS RowID, *
' FROM SomeTable;
'
' Usage (typical append query, automatic reset):
' INSERT INTO TempTable ( [RowID] )
' SELECT RowNumber(CStr([ID])) AS RowID, *
' FROM SomeTable
' WHERE (RowNumber("","",True)=0);
'
' 2018-08-23. Gustav Brock, Cactus Data ApS, CPH.
'
Public Function RowNumber( _
ByVal Key As String, _
Optional ByVal GroupKey As String, _
Optional ByVal Reset As Boolean) _
As Long
' Uncommon character string to assemble GroupKey and Key as a compound key.
Const KeySeparator As String = "¤§¤"
' Expected error codes to accept.
Const CannotAddKey As Long = 457
Const CannotRemoveKey As Long = 5
Static Keys As New Collection
Static GroupKeys As New Collection
Dim Count As Long
Dim CompoundKey As String
On Error GoTo Err_RowNumber
If Reset = True Then
' Erase the collection of keys and group key counts.
Set Keys = Nothing
Set GroupKeys = Nothing
Else
' Create a compound key to uniquely identify GroupKey and its Key.
' Note: If GroupKey is not used, only one element will be added.
CompoundKey = GroupKey & KeySeparator & Key
Count = Keys(CompoundKey)
If Count = 0 Then
' This record has not been enumerated.
'
' Will either fail if the group key is new, leaving Count as zero,
' or retrieve the count of already enumerated records with this group key.
Count = GroupKeys(GroupKey) + 1
If Count > 0 Then
' The group key has been recorded.
' Remove it to allow it to be recreated holding the new count.
GroupKeys.Remove (GroupKey)
Else
' This record is the first having this group key.
' Thus, the count is 1.
Count = 1
End If
' (Re)create the group key item with the value of the count of keys.
GroupKeys.Add Count, GroupKey
End If
' Add the key and its enumeration.
' This will be:
' Using no group key: Relative to the full recordset.
' Using a group key: Relative to the group key.
' Will fail if the key already has been created.
Keys.Add Count, CompoundKey
End If
' Return the key value as this is the row counter.
RowNumber = Count
Exit_RowNumber:
Exit Function
Err_RowNumber:
Select Case Err
Case CannotAddKey
' Key is present, thus cannot be added again.
Resume Next
Case CannotRemoveKey
' GroupKey is not present, thus cannot be removed.
Resume Next
Case Else
' Some other error. Ignore.
Resume Exit_RowNumber
End Select
End Function

UPDATE multiple table with same column name with condition for each value on MYSQL

I've a column "pid" and a lot of table on each database , then I want to update all table from every database with column "pid" and set 'pid' = 5 where 'pid' = 3 and set 'pid' = 6 where 'pid = '7' on 1 query .
I've find post like this and try to apply it:
Select 'UPDATE ' + TABLE_NAME + ' SET pid = ''5'' '
From INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME = 'pid'
Without condition for try it , then MYSQL just return me a select with value 0 .
'UPDATE ' + TABLE_NAME + ' SET pid = ''5'' '
0
Need a little help and explain for make this query work and understand how its work .
Really thanks everyone :)
UPDATE table_name
SET pid = 5
WHERE pid = 3;
It should be implemented like this. You simply tell to update the table named table_name to set pid as '5' wherever it finds it as '3'.
Read also here. ;)

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.