Accessing MS SQL Topic is solved

Get help with using AutoHotkey (v2 or newer) and its commands and hotkeys
Thalon
Posts: 17
Joined: 24 Nov 2016, 04:55

Accessing MS SQL

09 Jan 2024, 08:46

Hi! Long time no see :D

I've used a script of mine for nearly a decade now and it's latest version made use of ADOSQL written by VXE.
It does read and write from/to a MS SQL database.

Today I tried to convert my program from AHK V1 to V2 and it at least starts after some changes, but I can't figure out how to update the ADOSQL-Script.

I've tried the tip provided here as someone else has/had the exactly same problem:
viewtopic.php?f=82&t=114566

But it didn't help. The OP also posted the exact script I'm using. The original link is sadly also dead.

Are there working solutions for MS SQL 2 out there or do I have to install AHK V1 for now to still use (and extend) my script on a new computer?

Thanks a lot!
Thalon
garry
Posts: 3795
Joined: 22 Dec 2013, 12:50

Re: Accessing MS SQL

10 Jan 2024, 07:33

there is a converter from AHK-V1 to V2 , but I think not help in this case > how to update the ADOSQL-Script
https://github.com/mmikeww/AHK-v2-script-converter
Thalon
Posts: 17
Joined: 24 Nov 2016, 04:55

Re: Accessing MS SQL

10 Jan 2024, 09:27

garry wrote:
10 Jan 2024, 07:33
there is a converter from AHK-V1 to V2 , but I think not help in this case > how to update the ADOSQL-Script
https://github.com/mmikeww/AHK-v2-script-converter
Yeah, I've tried the converter already. But still have errors when running commands.
just me
Posts: 9576
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Accessing MS SQL

10 Jan 2024, 10:52

Moin @Thalon,

would you please show your faulty v2 attempt?
Thalon
Posts: 17
Joined: 24 Nov 2016, 04:55

Re: Accessing MS SQL

13 Jan 2024, 05:31

just me wrote:
10 Jan 2024, 10:52
Moin @Thalon,

would you please show your faulty v2 attempt?
Here it is:

Code: Select all

/*
###############################################################################################################
######                                      ADOSQL v5.04L - By [VxE]                                     ######
###############################################################################################################

	Wraps the utility of ADODB to connect to a database, submit a query, and read the resulting recordset.
	Returns the result as a new object (or array of objects, if the query has multiple statements).
	To instead have this function return a string, include a delimiter option in the connection string.

	For AHK-L (v1.1 or later).
	Freely available @ http://auto-hotkey.com/boards/viewtopic.php?p=365#p365

	IMPORTANT! Before you can use this library, you must have access to a database AND know the connection
	string to connect to your database.

	Varieties of databases will have different connection string formats, and different drivers (providers).
	Use the mighty internet to discover the connection string format and driver for your type of database.

	Example connection string for SQLServer (2005) listening on port 3456 and with a static IP:
	DRIVER={SQL SERVER};SERVER=192.168.0.12,3456;DATABASE=mydb;UID=admin;PWD=12345;APP=AHK
*/

Global ADOSQL_LastError, ADOSQL_LastQuery ; These super-globals are for debugging your SQL queries.

ADOSQL( Connection_String, Query_Statement ) {
; Uses an ADODB object to connect to a database, submit a query and read the resulting recordset.
; By default, this function returns an object. If the query generates exactly one result set, the object is
; a 2-dimensional array containing that result (the first row contains the column names). Otherwise, the
; returned object is an array of all the results. To instead have this function return a string, append either
; ";RowDelim=`n" or ";ColDelim=`t" to the connection string (substitute your preferences for "`n" and "`t").
; If there is more than one table in the output string, they are separated by 3 consecutive row-delimiters.
; ErrorLevel is set to "Error" if ADODB is not available, or the COM error code if a COM error is encountered.
; Otherwise ErrorLevel is set to zero.

	coer := "", txtout := 0, rd := "`n", cd := "CSV", str := Connection_String ; 'str' is shorter.

; Examine the connection string for output formatting options.
	If ( 9 < oTbl := 9 + InStr(";" str, ";RowDelim=") )
	{
		rd := SubStr(str, (oTbl)<1 ? (oTbl)-1 : (oTbl), 0 - oTbl + oRow := InStr(str ";", ";", 0, (oTbl)<1 ? (oTbl)-1 : (oTbl)))
		str := SubStr(str, 1, oTbl - 11) SubStr(str, (oRow)<1 ? (oRow)-1 : (oRow))
		txtout := 1
	}
	If ( 9 < oTbl := 9 + InStr(";" str, ";ColDelim=") )
	{
		cd := SubStr(str, (oTbl)<1 ? (oTbl)-1 : (oTbl), 0 - oTbl + oRow := InStr(str ";", ";", 0, (oTbl)<1 ? (oTbl)-1 : (oTbl)))
		str := SubStr(str, 1, oTbl - 11) SubStr(str, (oRow)<1 ? (oRow)-1 : (oRow))
		txtout := 1
	}

	;ComObjError( 0 ) ; We'll manage COM errors manually.

; Create a connection object. > http://www.w3schools.com/ado/ado_ref_connection.asp
; If something goes wrong here, return blank and set the error message.
	If !( oCon := ComObject("ADODB.Connection") )
        {
                ;ComObjError(1)
                ErrorLevel := "Error"
                ADOSQL_LastError := "Fatal Error: ADODB is not available."
		Return ""
        }

	oCon.ConnectionTimeout := 9 ; Allow 9 seconds to connect to the server.
	oCon.CursorLocation := 3 ; Use a client-side cursor server.
	oCon.CommandTimeout := 1800 ; A generous 30 minute timeout on the actual SQL statement.
	oCon.Open( str ) ; open the connection.

; Execute the query statement and get the recordset. > http://www.w3schools.com/ado/ado_ref_recordset.asp
	If !( coer := A_LastError )
		oRec := oCon.execute( ADOSQL_LastQuery := Query_Statement )

	If !( coer := A_LastError ) ; The query executed OK, so examine the recordsets.
	{
		o3DA := [] ; This is a 3-dimensional array.
		While IsObject( oRec )
			If !oRec.State ; Recordset.State is zero if the recordset is closed, so we skip it.
				oRec := oRec.NextRecordset()
			Else ; A row-returning operation returns an open recordset
			{
				oFld := oRec.Fields
				o3DA.Push( oTbl := [] )
				oTbl.Push( oRow := [] )

				Loop cols := oFld.Count ; Put the column names in the first row.
					;oRow[ A_Index ] := oFld.Item( A_Index - 1 ).Name
					oRow[ A_Index ] := oFld.Item[ A_Index ].Name

				While !oRec.EOF ; While the record pointer is not at the end of the recordset...
				{
					;oTbl.Insert( oRow := [] )
					oTbl.Push( oRow := [] )
					oRow.SetCapacity( cols ) ; Might improve performance on huge tables??
					Loop cols
						;oRow[ A_Index ] := oFld.Item( A_Index - 1 ).Value	
						oRow[ A_Index ] := oFld.Item[ A_Index - 1 ].Value	
					oRec.MoveNext() ; move the record pointer to the next row of values
				}

				oRec := oRec.NextRecordset() ; Get the next recordset.
			}

		If (txtout) ; If the user wants plaintext output, copy the results into a string
		{
			Query_Statement := "x"
			Loop o3DA.MaxIndex()
			{
				Query_Statement .= rd rd
				oTbl := o3DA[ A_Index ]
				Loop oTbl.MaxIndex()
				{
					oRow := oTbl[ A_Index ]
					Loop oRow.MaxIndex()
						If ( cd = "CSV" )
						{
							str := oRow[ A_Index ]
							str := StrReplace(str, "`"", "`"`"")
							If !ErrorLevel || InStr(str, ",") || InStr(str, rd)
								str := "'" str "'"
							Query_Statement .= ( A_Index = 1 ? rd : "," ) str
						}
						Else
							Query_Statement .= ( A_Index = 1 ? rd : cd ) oRow[ A_Index ]
				}
			}
			Query_Statement := SubStr(Query_Statement, (2 + 3 * StrLen( rd ))<1 ? (2 + 3 * StrLen( rd ))-1 : (2 + 3 * StrLen( rd )))
		}
	}
	Else ; Oh NOES!! Put a description of each error in 'ADOSQL_LastError'.
	{
		oErr := oCon.Errors ; > http://www.w3schools.com/ado/ado_ref_error.asp
		Query_Statement := "x"
		Loop oErr.Count
		{
			oFld := oErr.Item( A_Index - 1 )
			str := oFld.Description
			Query_Statement .= "`n`n" SubStr(str, (1 + InStr(str, "]", 0, (2 + InStr(str, "][", 0, -1))<1 ? (2 + InStr(str, "][", 0, -1))-1 : (2 + InStr(str, "][", 0, -1))))<1 ? (1 + InStr(str, "]", 0, (2 + InStr(str, "][", 0, -1))<1 ? (2 + InStr(str, "][", 0, -1))-1 : (2 + InStr(str, "][", 0, -1))))-1 : (1 + InStr(str, "]", 0, (2 + InStr(str, "][", 0, -1))<1 ? (2 + InStr(str, "][", 0, -1))-1 : (2 + InStr(str, "][", 0, -1)))))				. "`n   Number: " oFld.Number				. ", NativeError: " oFld.NativeError				. ", Source: " oFld.Source				. ", SQLState: " oFld.SQLState
		}
		ADOSQL_LastError := SubStr(Query_Statement, 4)
		Query_Statement := ""
		txtout := 1
	}

; Close the connection and return the result. Local objects are cleaned up as the function returns.
	oCon.Close()
	;ComObjError( 1 )
	ErrorLevel := coer
	Return txtout ? Query_Statement : o3DA.MaxIndex() = 1 ? o3DA[1] : o3DA
} ; END - ADOSQL( Connection_String, Query_Statement )
Here is a simple testscript:

Code: Select all

#Requires AutoHotkey v2.0

#Include adosql.ahk

ConnectionString := "DRIVER={SQL SERVER};SERVER=SQL006;DATABASE=B_140_DEV;Trusted_Connection=True"
Result := ADOSQL( ConnectionString ";coldelim=`t", "
(
    Select Description from [OM - Project] where [No_] = '010621'
)")
MsgBox Result
Callstack:

Code: Select all

Call stack:
*#1 (40) : [ADOSQL] oTbl.Push( oRow := [] )
*#1 (98) : [] Result := ADOSQL( ConnectionString ";coldelim=	", "Select Description from [OM - Project] where [No_] = '010621'")
> Auto-execute
Errorline:
▶ 042: oRow[ A_Index ] := oFld.Item[ A_Index ].Name

I've had other errors, but this one I'm stuck at:
Error: (0x800A0CC1)
Ein Objekt, das dem angeforderten Namen oder dem Ordinalverweis entspricht, kann nicht gefunden werden.
Source: ADODB.Fields
This should be the correct translation:
error ''800a0cc1'' .Item cannot be found in the collection.
Thanks!
Ruevil2
Posts: 174
Joined: 14 Jul 2014, 10:39

Re: Accessing MS SQL  Topic is solved

29 Jan 2024, 22:21

I ran into this same problem and ended up dealing with it.

Check here for working V2 modification

viewtopic.php?f=83&t=125462
Thalon
Posts: 17
Joined: 24 Nov 2016, 04:55

Re: Accessing MS SQL

05 Feb 2024, 08:12

Ruevil2 wrote:
29 Jan 2024, 22:21
I ran into this same problem and ended up dealing with it.

Check here for working V2 modification

viewtopic.php?f=83&t=125462
Thank you soo much!
I've just tested it and it works quite fine :-)

Return to “Ask for Help (v2)”

Who is online

Users browsing this forum: No registered users and 15 guests