Use macro to execute SQL command

Creating a macro - Writing a Script - Using the API (OpenOffice Basic, Python, BeanShell, JavaScript)
Post Reply
idachan
Posts: 44
Joined: Tue Jul 05, 2011 11:33 am

Use macro to execute SQL command

Post by idachan »

HI!
I would like to ask that how to use macro to execute SQL command?
I want to execute

Code: Select all

shutdown script
when I close the file.
Thank you!
OpenOffice 3.0 on Windows XP
User avatar
Charlie Young
Volunteer
Posts: 1559
Joined: Fri May 14, 2010 1:07 am

Re: Use macro to execute SQL command

Post by Charlie Young »

idachan wrote:HI!
I would like to ask that how to use macro to execute SQL command?
I want to execute

Code: Select all

shutdown script
when I close the file.
Thank you!
In Basic from within Base

Code: Select all

Dim oStatement As Object
	
	oStatement = ThisComponent.CurrentController.ActiveConnection.createStatement()
 	oStatement.execute("shutdown script")
Apache OpenOffice 4.1.1
Windows XP
rudolfo
Volunteer
Posts: 1488
Joined: Wed Mar 19, 2008 11:34 am
Location: Germany

Re: Use macro to execute SQL command

Post by rudolfo »

Ida,
I hope you are aware what you are going to do. I guess the idea behind running shutdown script upon closing the OOo Base File is to get a more stable (or more compact) embedded database. You'd better run a search for the two phrases shutdown and script in the search functionality of the forum (upper right). There are several posts from those who are familiar with HSQLDB that explain that the database is written from a temporary cache location to the .odb zip archive. I picked out one example by r4zoli.
In short the process of writing back the cached database into the archive file is not really robust. Processing a radical statement as "shutdown script" direclty before (or in parallel -- who of us can know?) to this sensitive process has a good chance to make it all worse.

Another related issue is that you need to retrieve a handle of the active connection in the macro. The way how to do this differs depending if you are in the main Base window or in a form. And yes the file is about to close. Maybe the first operation when closing the file is to close the connection before any on-close macros are executed.

Make sure that you run tests with a database that doesn't hurt you when you loose it. And be prepared for debbuging and strange timing issues.

Frankly if you are looking for stability (and/or multiuser access) look for the external databases.
OpenOffice 3.1.1 (2.4.3 until October 2009) and LibreOffice 3.3.2 on Windows 2000, AOO 3.4.1 on Windows 7
There are several macro languages in OOo, but none of them is called Visual Basic or VB(A)! Please call it OOo Basic, Star Basic or simply Basic.
idachan
Posts: 44
Joined: Tue Jul 05, 2011 11:33 am

Re: Use macro to execute SQL command

Post by idachan »

Dear Charlie Young,
Thank you for your reply,but there exists an error when running the macro.
"Property or method not found:ActiveConnection"
How to deal with it?Thank you.

Dear rudolfo,
Yup,I know what am I doing^^
I was new to Base and database,and going to handle a huge database.Then I chose Base to help me. I discovered that the file size was increased rapidly, so I found that Base would backup data.Therefore I came hereto search any method and I got a SQL command "shutdown script".It's really reduced the size!However I don't want to execute this command every time,so I ask for help^^
I want to execute this command in event "document is going to close".
Thank you for you reply and suggestion.
OpenOffice 3.0 on Windows XP
User avatar
Charlie Young
Volunteer
Posts: 1559
Joined: Fri May 14, 2010 1:07 am

Re: Use macro to execute SQL command

Post by Charlie Young »

idachan wrote:Dear Charlie Young,
Thank you for your reply,but there exists an error when running the macro.
"Property or method not found:ActiveConnection"
How to deal with it?Thank you.
That means you don't have an ActiveConnection. :D

An ActiveConnection is normally established when you view a table or execute a query or some such activity, but you can also make it happen in your macro.

Code: Select all

	
	if IsNull(ThisComponent.CurrentController.ActiveConnection) then
		ThisComponent.CurrentController.connect
	endif

I don't think the IsNull check is really necessary, but it's good form and it doesn't hurt.
Apache OpenOffice 4.1.1
Windows XP
idachan
Posts: 44
Joined: Tue Jul 05, 2011 11:33 am

Re: Use macro to execute SQL command

Post by idachan »

Dear Charlie,
I just try the macro, but same error exists again but point to "if IsNull(ThisComponent.CurrentController.ActiveConnection) then"@@
Here is the completed macro:

Code: Select all

sub executeSQLcmd
   	Dim oStatement As Object
   	if IsNull(ThisComponent.CurrentController.ActiveConnection) then
       ThisComponent.CurrentController.connect
    endif
    oStatement = ThisComponent.CurrentController.ActiveConnection.createStatement()
    oStatement.execute("shutdown script")
end sub
Thank you.
OpenOffice 3.0 on Windows XP
User avatar
Charlie Young
Volunteer
Posts: 1559
Joined: Fri May 14, 2010 1:07 am

Re: Use macro to execute SQL command

Post by Charlie Young »

Are you sure you are running this macro from within a Base document? what pops up when you run this?

Put it in before any references to ActiveConnection.

Code: Select all


	if ThisComponent.supportsService("com.sun.star.sdb.OfficeDatabaseDocument") then
		MsgBox("I'm in Base")
	else
		MsgBox("I'm somewhere else.")
	endif
Apache OpenOffice 4.1.1
Windows XP
RPG
Volunteer
Posts: 2250
Joined: Tue Apr 14, 2009 7:15 pm
Location: Netherlands

Re: Use macro to execute SQL command

Post by RPG »

LibreOffice 7.1.4.2 on openSUSE Leap 15.2
idachan
Posts: 44
Joined: Tue Jul 05, 2011 11:33 am

Re: Use macro to execute SQL command

Post by idachan »

Dear Charlie,

Sorry that reply you late.
I run your macro,

Code: Select all

       if ThisComponent.supportsService("com.sun.star.sdb.OfficeDatabaseDocument") then
          MsgBox("I'm in Base")
       else
          MsgBox("I'm somewhere else.")
       endif
A message box written "I'm in Base" was shown.

What should I do next step?
Thank you!
OpenOffice 3.0 on Windows XP
User avatar
Charlie Young
Volunteer
Posts: 1559
Joined: Fri May 14, 2010 1:07 am

Re: Use macro to execute SQL command

Post by Charlie Young »

idachan wrote:Dear Charlie,

Sorry that reply you late.
I run your macro,

Code: Select all

       if ThisComponent.supportsService("com.sun.star.sdb.OfficeDatabaseDocument") then
          MsgBox("I'm in Base")
       else
          MsgBox("I'm somewhere else.")
       endif
A message box written "I'm in Base" was shown.

What should I do next step?
Thank you!
Then I guess you're in Base. OK, dispose of that piece of code.

What happens if you try something other than "Shutdown Script?" Say try to create a backup table (SELECT INTO). It seems strange that you are able to load an .odb but not connect to it.
Apache OpenOffice 4.1.1
Windows XP
idachan
Posts: 44
Joined: Tue Jul 05, 2011 11:33 am

Re: Use macro to execute SQL command

Post by idachan »

Dear Charlie,
I'm sorry that I cannot get your meaning...
could u give me some examples to try?
btw, is it correct for my previous macro?
thank you!
Ida
OpenOffice 3.0 on Windows XP
User avatar
Charlie Young
Volunteer
Posts: 1559
Joined: Fri May 14, 2010 1:07 am

Re: Use macro to execute SQL command

Post by Charlie Young »

idachan wrote:Dear Charlie,
I'm sorry that I cannot get your meaning...
could u give me some examples to try?
btw, is it correct for my previous macro?
thank you!
Ida
The last macro was just to be sure you were running from Base and not some other app. Yes, it was correct.

An example, where a valid table name in your database should be substituted for SomeTable, and the placement of quotation marks is important.

Code: Select all

Sub executeSQL()
	Dim oStatement As Object
	Dim oDoc As Object
	
	oDoc = ThisComponent
	if IsNull(oDoc.CurrentController.ActiveConnection) then
		oDoc.CurrentController.connect
	endif
	
	oStatement = oDoc.CurrentController.ActiveConnection.createStatement()
 	oStatement.execute("SELECT * INTO ""SomeTableBackup"" FROM ""SomeTable""") 
 	
End Sub
Note that if this is successful, you will need to delete "SomeTableBackup" before running it again.
Apache OpenOffice 4.1.1
Windows XP
rudolfo
Volunteer
Posts: 1488
Joined: Wed Mar 19, 2008 11:34 am
Location: Germany

Re: Use macro to execute SQL command

Post by rudolfo »

Sorry for jumping in again. But this thread seems to become a funny interpretation of remote debugging ... with Charlie as the remote debugger. Surely, Charlie is one of the best debuggers you can get, but still posting in this thread introduces a lot of waiting time into the typical programming cycle (writing code, running the macro, inspect the errors with a debugger, modify the code, run the macro again ...).
One of the major rules of macro programming in OpenOffice (and probably other macro enabled programs, as well) is: If you run into an error, inspect the object with that you are working. The Basic function "IsNull" is a very basic object inspection method (and probably one of the rare kind that can be used with human remote debugging).
But it might be easier if you follow the Guide in the Online Help (press F1) and then "Macros and Programming" -> "Guides" -> "Debugging a Basic Program".

If you are running your macro from an event handler (maybe the CloseDocument Event?) you can't use the Basic Debbuger with all its feature. In this case it is easier to get one of the Object inspection tool extensions MRI or Xray.
For MRI your macro code could be:

Code: Select all

Sub executeSQL()
   Dim oStatement As Object
   Dim oDoc As Object
   Dim oMRI As Object

   Globalscope.BasicLibraries.LoadLibrary("MRILib")
   oMRI = CreateUnoService("mytools.Mri")

   oDoc = ThisComponent

   oMRI.inspect( oDoc.CurrentController )

   if IsNull(oDoc.CurrentController.ActiveConnection) then
      oDoc.CurrentController.connect
   endif
   
   oStatement = oDoc.CurrentController.ActiveConnection.createStatement()
   oStatement.execute("SELECT * INTO ""SomeTableBackup"" FROM ""SomeTable""")
   
End Sub
You can click one certain properties and methods and they will be shown in the window. If a property is again a UNO object it will have a list of properties and methods as well. The following screenshot show how it looks for me, if I have a Base document opened.
Inspect a Base document with MRI
Inspect a Base document with MRI
OpenOffice 3.1.1 (2.4.3 until October 2009) and LibreOffice 3.3.2 on Windows 2000, AOO 3.4.1 on Windows 7
There are several macro languages in OOo, but none of them is called Visual Basic or VB(A)! Please call it OOo Basic, Star Basic or simply Basic.
RPG
Volunteer
Posts: 2250
Joined: Tue Apr 14, 2009 7:15 pm
Location: Netherlands

Re: Use macro to execute SQL command

Post by RPG »

Hello

Maybe the next example can work but it is not sure. But the macros given by Charlie Young are perfect macros. I do use ThisdatabaseDocument and not ThisComponent. That I use an other example for SQL is not important.

This can work maybe work always in a form what is part of a databasedocument. Also it can be runned in the IDE.

Code: Select all

sub executeSQLcmd
' This can work direct in the IDE and with a button in a form
    Dim oStatement As Object
    if IsNull(Thisdatabasedocument.CurrentController.ActiveConnection) then
       Thisdatabasedocument.CurrentController.connect
    endif
    oStatement = Thisdatabasedocument.CurrentController.ActiveConnection.createStatement()
    dim resultset
    resultset=oStatement.executequery("call CURRENt_TIME")
    resultset.next
    print resultset.getstring(1)
end sub
I asume this can be runned in ll forms but not from the IDE.

Code: Select all

sub executeSQLcmd(oEvent as object)
' This must be activated by a button
' I assume this can work in all forms but you can not run it in the IDE
dim oButton ,oForm
oButton=oEvent.source.model
'When the line above is blue then you run it possible in the IDE
oForm=oButton.parent ' We assumed that when you come here there is always an activ connection
    Dim oStatement As Object
    oStatement = oForm.ActiveConnection.createStatement()
    dim resultset
    resultset=oStatement.executequery("call CURRENt_TIME")
    resultset.next
    print resultset.getstring(1)
end sub
This code is an other example what can work but has other problems.

Code: Select all

'This works only for a form in a database document and not for a standalone form
'It works when it is activate from the IDE and assume there is a connectio to the database
sub executeSQLcmd
' This must be activated by a button or on an other way
' I assume this can work in all forms who are stored in the database.  but you can not run it in the IDE
dim oDoc,oDatabaseDocument
Dim oStatement As Object

oDoc=Thiscomponent
oDatabaseDocument=oDoc.parent
oStatement = oDatabaseDocument.getCurrentController.ActiveConnection.createStatement()
dim resultset
resultset=oStatement.executequery("call CURRENt_TIME")
resultset.next
print resultset.getstring(1)
end sub
I want make clear that the question seems simple: I want a little macro. But when you not describe in what kind of document you use the macro and also not describe how you activate the macro then it can not work for you.

Maybe an other problem can be where do you store the macros. Most of this macros work only when they are stored in the document and not My Macros. When you store the macros in My macros you can expect other problems. This also depends on what kind of document you use and also how do you call the macro.

Romke
LibreOffice 7.1.4.2 on openSUSE Leap 15.2
Post Reply