How to populate matlab GUI edit texts with values from MySQL database? - mysql

I have created a table with 10 columns in matlab database toolbox. How do i retrieve the values and show them in matlab GUI? when I use the code below, I get Undefined function 'fetch' for input arguments of type 'double' error. Can anybody tell me what is wrong with my code?
f = getappdata(0,'fvalue');
%Set preferences with setdbprefs.
setdbprefs('DataReturnFormat', 'cellarray');
setdbprefs('NullStringRead', 'null');
%Make connection to database.
conn = database('marine_invertebrates', '', '');
%Read data from database.
curs = fetch(conn, sprintf(['SELECT description.commonName'...
' , description.scientificName'...
' , description.kingdom'...
' , description.phylum'...
' , description.subphylum'...
' , description.class'...
' , description.order'...
' , description.family'...
' , description.genus'...
' , description.species'...
' FROM marine_cbir.description WHERE description.imageID = "%s"'], num2str(f)));
curs = fetch(curs);
close(curs);
%Assign data to output variable
results = curs.Data;
commonName = set(handles.edit11,'String');
display (commonName);
scientificName = set(handles.edit1,'String');
display (scientificName);
kingdom = set(handles.edit2,'String');
display (kingdom);
phylum = set(handles.edit3,'String');
display (phylum);
subphylum = set(handles.edit4,'String');
display (subphylum);
class = set(handles.edit5,'String');
display (class);
order = set(handles.edit6,'String');
display (order);
family = set(handles.edit7,'String');
display (family );
genus = set(handles.edit8,'String');
display (genus);
species = set(handles.edit9,'String');
display (species );

Related

How to get a value from func/sp to a case statement using dynamic SQL?

hoping someone might be able to help me with a bit of an issue. Essentially i'm trying to get a rough size of all of the fields in my database as i'd like to do some math on it to guesstimate what the size will be with a compression technique applied to it.
I can do this for most fields by looking at the datatype and using the number of rows to get the number of bytes it's taking up. However on something like a varchar(max) field this is not as easy and so i decided to approach this by getting the average length within the column and multiplying by number of rows. But i've hit a snag which i'll describe below.
I have the following stored proc (i tried a function too but you can't call dynamic SQL from a function).
CREATE PROCEDURE dbo.getFieldSize(#column varchar(255), #table varchar(255), #ret decimal(15,7) OUTPUT)
AS
BEGIN
DECLARE #lengthSQL varchar(50)
/SET #lengthSQL = 'SELECT #ret = AVG(DATALENGTH(' + #column + ')) FROM [' + #table +']'/
SET #lengthSQL = 'SELECT #ret = AVG(DATALENGTH(' + #column + ')) FROM ' + #table
exec sp_executesql #lengthSQL
RETURN #ret
END
GO
And then i call it using...
SELECT b.TABLE_SCHEMA as 'Schema',
CASE WHEN DATA_TYPE IN ('nvarchar') AND CHARACTER_MAXIMUM_LENGTH <> -1 AND c.distinctItems <> 0 AND c.totalCount <> 0 THEN exec('select max(len(' + b.TABLE_CATALOG + ' + '.' + ' + b.COLUMN_NAME + '))')
FROM ....
The above is basically just checking to make sure it is a varchar(max) field and contains some values within the column. I then try and execute the SP and pass the column name and table name for which i need the avg length but i get the following error.
Msg 156, Level 15, State 1, Line 57
Incorrect syntax near the keyword 'exec'.
I learned you cannot call a dynamic SQL from a function and you cannot call a SP from a CASE statement. So at this point it seems like it's a catch 22 and i cannot do what i need using SQL. Can anyone think of any workarounds or i'm I out of luck on this?
Actually, you can do Dynamic SQL in a scalar UDF, it just needs to be a SQLCLR UDF ;-). But this is fairly simple to do using the in-process / internal connection (i.e. SqlConnection("Context Connection = true;");). Meaning, the assembly can be set to SAFE.
Also, object / column / index names are all NVARCHAR. And objects (if not also the others) are declared as sysname which is an alias for NVARCHAR(128). Just FYI.
So, something like the following (which I have tested and it does work):
[Microsoft.SqlServer.Server.SqlFunction(Name = "GetAvgBytes",
IsDeterministic = false, IsPrecise = true, DataAccess = DataAccessKind.Read)]
public static SqlInt32 GetAvgBytes([SqlFacet(MaxSize = 128)] SqlString TableName,
[SqlFacet(MaxSize = 128)] SqlString ColumnName)
{
int _AvgBytes = -1;
SqlConnection _Connection = new SqlConnection("Context Connection = true;");
SqlCommand _Command = _Connection.CreateCommand();
_Command.CommandType = CommandType.Text;
_Command.CommandText = "SELECT #AvgBytes = AVG(DATALENGTH(" + ColumnName.Value
+ ")) FROM " + TableName.Value + " WITH (NOLOCK);";
SqlParameter _Param = new SqlParameter("#AvgBytes", DbType.Int32);
_Param.Direction = ParameterDirection.Output;
_Command.Parameters.Add(_Param);
try
{
_Connection.Open();
_Command.ExecuteNonQuery();
_AvgBytes = (int)_Param.Value;
}
finally
{
_Connection.Close();
}
return _AvgBytes;
}

SQLTransaction2 : Operation cannot be performed on an active transaction FreePascal - Code Typhon

I would like some help solving this error message.
I am using Code Typhon32 V4.9 on Windows 7 Pro.
I had a project connecting to a firebird database,
Single form which works fine- No problems.
I added a 2nd form to be my data entry form linked to another Database in
Firebird - I need both databases in one project.
Since adding the 2nd form I am getting the following error when I close code typhon and when I close Form1 while using the debugger: "SQLTransaction2 : Operation cannot be performed on an active transaction"
I have tried numerous of solution found on the internet but can not solve it.
I have a button that open the 2nd from as Follows:
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
frmContributions := TfrmContributions.Create(nil);
try
frmContributions.ShowModal;
finally
frmContributions.Free;
end;
end;
Here is my 2nd form Code:
unit uFirebirdDemo1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, sqldb, IBConnection, pqconnection, db, FileUtil, Forms,
Controls, Graphics, Dialogs, StdCtrls, DBGrids, DbCtrls;
type
TfrmContributions = class(TForm)
btnUpdate: TButton;
btnDeleteProgrammer: TButton;
dsProgrammer: TDatasource;
dbgrdProgrammer: TDBGrid;
dbnavProgrammer: TDBNavigator;
IBConnection2: TIBConnection;
sqlqProgrammer: TSQLQuery;
SQLScript1: TSQLScript;
SQLTransaction2: TSQLTransaction;
procedure btnDeleteProgramClick(Sender: TObject);
procedure btnUpdateClick(Sender: TObject);
procedure btnUpdateProgramsClick(Sender: TObject);
procedure btnDeleteProgrammerClick(Sender: TObject);
procedure dbgrdCombinedTitleClick(Column: TColumn);
procedure dbgrdProgrammerTitleClick(Column: TColumn);
procedure dbgrdProgramsTitleClick(Column: TColumn);
procedure edtSearchChange(Sender: TObject);
procedure Savechanges;
procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
end;
var
frmContributions: TfrmContributions;
implementation
{$R *.lfm}
procedure TfrmContributions.btnUpdateClick(Sender: TObject);
begin
sqlqProgrammer.Edit;
sqlqProgrammer.Post;
sqlqProgrammer.ApplyUpdates(1);
SQLTransaction2.CommitRetaining;
end;
procedure TfrmContributions.btnDeleteProgrammerClick(Sender: TObject);
begin
SQLScript1.Script.Text:= 'Delete from Programmer WHERE ID = ' + dbgrdProgrammer.Columns[0].Field.AsString + ';';
SQLScript1.Execute;
SQLTransaction2.CommitRetaining;
sqlqProgrammer.Refresh;
end;
procedure TfrmContributions.dbgrdProgrammerTitleClick(Column: TColumn);
begin
sqlqProgrammer.Close;
SQLTransaction2.Active := TRUE;
sqlqProgrammer.SQL.Text := 'Select * from Programmer ORDER BY ID DESC';
sqlqProgrammer.Open;
end;
procedure TfrmContributions.Savechanges;
// Saves edits done by user, if any.
begin
try
if SQLTransaction2.Active then
// Only if we are within a started transaction
// otherwise you get "Operation cannot be performed on an inactive dataset"
begin
sqlqProgrammer.ApplyUpdates; //Pass user-generated changes back to database...
SQLTransaction2.Commit; //... and commit them using the transaction.
//SQLTransaction2.Active now is false
end;
except
on E: EDatabaseError do
begin
MessageDlg('Error', 'A database error has occurred. Technical error message: ' +
E.Message, mtError, [mbOK], 0);
end;
end;
end;
procedure TfrmContributions.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
SaveChanges;
sqlqProgrammer.Close;
SQLTransaction2.Commit;
SQLTransaction2.RollBack;
SQLTransaction2.Active := False;
IBConnection2.Connected := False;
end;
end.
I tried adding a formclose to my first form as follows in order to solved the problem
but it does not seem to be doing anything:
procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
frmContributions.SaveChanges;
frmContributions.SQLTransaction2.RollBack;
frmContributions.SQLTransaction2.Active := False;
frmContributions.IBConnection2.Connected := False;
end;
I have tried different solutions found on the internet but I am still getting:
"SQLTransaction2 : Operation cannot be performed on an active transaction" when i
close my project using the debugger, and also I get the same error when closing down
code typhon.
Here is the lfm file:
object frmContributions: TfrmContributions
Left = 816
Height = 415
Top = 172
Width = 774
Caption = 'Data Entry for Promo'
ClientHeight = 415
ClientWidth = 774
Color = clHighlight
OnClose = FormClose
LCLVersion = '1.3'
object btnUpdate: TButton
Left = 536
Height = 25
Top = 376
Width = 168
Caption = 'Update programmers'
OnClick = btnUpdateClick
TabOrder = 0
end
object dbgrdProgrammer: TDBGrid
Left = 16
Height = 360
Top = 0
Width = 744
Color = clWindow
Columns = <
item
Title.Caption = 'ID'
Width = 60
FieldName = 'ID'
end
item
Title.Caption = 'DATESENT'
FieldName = 'DATESENT'
end
item
Title.Caption = 'COURSE'
Width = 140
FieldName = 'COURSE'
end
item
Title.Caption = 'PROMOTYPE'
Width = 140
FieldName = 'PROMOTYPE'
end
item
Title.Caption = 'LINK'
Width = 100
FieldName = 'LINK'
end
item
Title.Caption = 'VALUE'
Width = 50
FieldName = 'VALUECHART'
end
item
Title.Caption = 'TOTALSENT'
FieldName = 'TOTALSENT'
end
item
Title.Caption = 'NOTES'
FieldName = 'NOTES'
end>
DataSource = dsProgrammer
TabOrder = 1
OnTitleClick = dbgrdProgrammerTitleClick
end
object dbnavProgrammer: TDBNavigator
Left = 280
Height = 25
Top = 376
Width = 241
BevelOuter = bvNone
ChildSizing.EnlargeHorizontal = crsScaleChilds
ChildSizing.EnlargeVertical = crsScaleChilds
ChildSizing.ShrinkHorizontal = crsScaleChilds
ChildSizing.ShrinkVertical = crsScaleChilds
ChildSizing.Layout = cclLeftToRightThenTopToBottom
ChildSizing.ControlsPerLine = 100
ClientHeight = 25
ClientWidth = 241
DataSource = dsProgrammer
Options = []
TabOrder = 2
VisibleButtons = [nbFirst, nbPrior, nbNext, nbLast, nbInsert, nbRefresh]
end
object btnDeleteProgrammer: TButton
Left = 64
Height = 25
Top = 376
Width = 201
Caption = 'Delete Selected Programmer'
OnClick = btnDeleteProgrammerClick
TabOrder = 3
end
object dsProgrammer: TDataSource
DataSet = sqlqProgrammer
left = 696
top = 168
end
object IBConnection2: TIBConnection
Connected = True
LoginPrompt = False
DatabaseName = '.......CONTRIBUTIONS.FDB'
KeepConnection = False
Password = 'password'
Transaction = SQLTransaction2
UserName = 'username'
HostName = 'hostname'
left = 696
top = 8
end
object SQLTransaction2: TSQLTransaction
Active = True
Action = caCommitRetaining
Database = IBConnection2
left = 696
top = 56
end
object sqlqProgrammer: TSQLQuery
IndexName = 'DEFAULT_ORDER'
FieldDefs = <
item
Name = 'ID'
DataType = ftInteger
Precision = -1
Size = 0
end
item
Name = 'DATESENT'
DataType = ftDate
Precision = -1
Size = 0
end
item
Name = 'PROMOTYPE'
DataType = ftString
Precision = -1
Size = 25
end
item
Name = 'COURSE'
DataType = ftString
Precision = -1
Size = 25
end
item
Name = 'LINK'
DataType = ftString
Precision = -1
Size = 450
end
item
Name = 'VALUECHART'
DataType = ftInteger
Precision = -1
Size = 0
end>
Active = True
Database = IBConnection2
Transaction = SQLTransaction2
SQL.Strings = (
'select * from Programmer order by ID DESC'
)
UpdateSQL.Strings = (
''
)
InsertSQL.Strings = (
''
)
DeleteSQL.Strings = (
''
)
Params = <>
UpdateMode = upWhereChanged
UsePrimaryKeyAsKey = False
left = 696
top = 224
end
object SQLScript1: TSQLScript
DataBase = IBConnection2
Transaction = SQLTransaction2
Directives.Strings = (
'SET TERM'
'COMMIT'
'#IFDEF'
'#IFNDEF'
'#ELSE'
'#ENDIF'
'#DEFINE'
'#UNDEF'
'#UNDEFINE'
)
Script.Strings = (
''
)
Terminator = ';'
CommentsinSQL = True
UseSetTerm = True
UseCommit = True
UseDefines = True
left = 696
top = 112
end
end
Thank you.
Actually I don't know exactly what should be next, but
(0) I'd move the database code into standalone TDataModule (outside the UI code) to make the code more straightforward to read and maintain. During this refactoring you may spot a hidden problem..
(1) this http://forum.lazarus.freepascal.org/index.php?topic=14301.0 seems to solve similar problem
(2) book Lazarus, the complete guide seems to have a chapter about TDataModule
(3) Martin Fowler wrote a book about refactoring and runs a site about the same at http://refactoring.com/
(4) some components don't behave well if they are active in the design mode. As it is actually different and more complicated scenario (lots of ifs with csDesigning in ComponentState, sequence diagram of events is different, nearly random and everything should be foolproof and re-entrant..). So safe side for production is to turn component's active state off in the design mode and activate them in code in a well defined order anticipated by the component authors
(5) If you experience the error only when in the debugger and it does not appear in production code I think that you can ignore the problem as the debugging environment is <see="(4)">

how to use dynamic query inside a function

i'm trying to create a function GETUSERPROP(prop, filter_prop, filter_value) that selects one item in database filtering by property and value
SET #_GET_PROP = "name";
SET #_FILTER_PROP = "id";
SET #_FILTER_VALUE = "15";
SET #q = CONCAT(
' SELECT ',
#_GET_PROP,
' FROM MYVIEW '
' WHERE 1 ',
' AND (`', #_FILTER_PROP, '` = "', #_FILTER_VALUE, '") '
);
PREPARE stmt FROM #q;
EXECUTE stmt;
the query outside function is running fine, but when I try to put this inside a function, I get the error
mysql dynamic sql is not allowed in stored function or trigger
I need this as a function to use inside other queries, like this:
SELECT
GETUSERPROP("name", "id", "15") AS name,
GETUSERPROP("age", "id", "15") AS age
From error message it is obvious we cannot use dynamic sql in function. Dynamic sql is only possible in procedure. So you have to think in alternative. If number of combination is not too much then you can use IF statement for each possible combination for example.
IF #_GET_PROP = 'name' AND #_FILTER_PROP = 'ID' THEN
SELECT name from MYVIEW where id = #_FILTER_VALUE;
ELSE IF #_GET_PROP = 'Agen' AND #_FILTER_PROP = 'ID' THEN
SELECT name from MYVIEW where id = #_FILTER_VALUE;
................
...............
and so on..
or something like this
SELECT CASE #_GET_PROP WHen 'name' then name when 'id' then ID when 'Age' then Age END from MYVIEW where
((#_FILTER_PROP = 'ID' AND id = #_FILTER_VALUE)
or (#_FILTER_PROP = 'name' AND name = #_FILTER_VALUE)
or (#_FILTER_PROP = 'age' AND age = #_FILTER_VALUE)
) ;

SQL script to create a database using a variable name

I'm trying to create a generic script to create a database and want to pass the database name as a variable; but it's not working.
Here is my code so far
DECLARE #ID sysname;
SET #ID = 'test'
SET #ID = QUOTENAME(#ID)
CREATE DATABASE #ID
ON PRIMARY
( NAME = [' + #ID + '], FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\DATA\' +#ID+ '.mdf' , SIZE = 211968KB ,
MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB )
LOG ON
( NAME = [' + #ID + '_log'], FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\DATA\'#ID + '_log.ldf' , SIZE = 149696KB , MAXSIZE = 2048GB , FILEGROWTH = 10%)
which gives me the following error:
Incorrect syntax near '#ID'.
If you can use SQLCMD mode in SSMS (SQLCMD Mode in the Query menu) or execute your script with sqlcmd.exe, you can use a SQLCMD scripting variable:
:setvar ID "test"
CREATE DATABASE [$(ID)]
ON PRIMARY ( NAME = ['$(ID)_Primary'], FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\DATA\$(ID).mdf' , SIZE = 211968KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB ) LOG ON ( NAME = ['$(ID)_log'], FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\DATA\$(ID)_log.ldf' , SIZE = 149696KB , MAXSIZE = 2048GB , FILEGROWTH = 10%)
From the command line, you would need to comment out the :setvar ID "test" statement (i.e. --:setvar ID "test") and run the script like so...
sqlcmd.exe -E -i YourScript.sql -v ID="real"
...assuming Windows authentication, a local, default instance of SQL Server, and YourScript.sql in the current directory.
The key is the -v command-line option to specify the name of the SQLCMD variable you wish to set and its value.
Using a SQLCMD variable like this is essentially what SSDT does under the hood.

How do I set the language of Input Control?

Here is my Input Control:
Note that the Info in the "Course Group" (Single Select Query) is in English
Here is the Query that gets the data in "Course Group"
select distinct(cog.cog_id) id, concat(cd.cd_shortdescription, '
(', cn.cn_shortname,' - ', cog.cog_org_be_id, ' - ', cd_code.cd_code, ')')
coursegroup
from es_exam_statistics_ft es, cg_classgroup cg, org_organisation org,
cn_campusname cn, cog_coursegroup cog, cd_codedescription cd, cd_code
where es.es_cg_id = cg.cg_id
and es.es_cog_id = cog.cog_id
and cog.cog_coursegroup_cd_id = cd.cd_id
and cd.cd_id = cd_code.cd_id
and org.org_be_id = cog.cog_org_be_id
and org.org_campusid = cn.cn_campusid
and cg.cg_startdate >= $P{startDate}
and cg.cg_enddate <= $P{endDate}
and cd.cd_language_id = 3
and cn.cn_language_id = 3
order by coursegroup
The problem comes with the lines i have made bold
Language Id's
2=Afrikaans
3=English
Now as you can see, the Query is hard-coded so that the language is always English, So if a user logs in, in a different language, the data in the input control will always be English
I tried replacing the value 3 form query (and cd.cd_language_id = 3) with "$P{REPORT_LOCALE}.getDisplayLanguage().equals("English") ? new Integer(3): new Integer(2)"
Which works in the XML of a Report, but doesn't work in the input Controls Query
How do I solve this issue ?
You cant change language of input controls value because these values are stored in database, Input control only fetch the data from database whatever data is stored in database, if in database its stored in other language then only you can change the input controls values.
To change the input values at JasperReport server level :-
1:- Create one more input control(p_language) to ask the Language
(value column (id) and visible column(language desc))
2:- then create a casecading input control to fetch the value of course group
using this query.
select distinct(cog.cog_id) id, concat(cd.cd_shortdescription, '
(', cn.cn_shortname,' - ', cog.cog_org_be_id, ' - ', cd_code.cd_code, ')')
coursegroup
from es_exam_statistics_ft es, cg_classgroup cg, org_organisation org,
cn_campusname cn, cog_coursegroup cog, cd_codedescription cd, cd_code
where es.es_cg_id = cg.cg_id
and es.es_cog_id = cog.cog_id
and cog.cog_coursegroup_cd_id = cd.cd_id
and cd.cd_id = cd_code.cd_id
and org.org_be_id = cog.cog_org_be_id
and org.org_campusid = cn.cn_campusid
and cg.cg_startdate >= $P{startDate}
and cg.cg_enddate <= $P{endDate}
and cd.cd_language_id = $P{p_language}
and cn.cn_language_id = $P{p_language}
order by coursegroup