I am building an App, DUNA, that references and writes data to an sqlite database. One of the functions I have is to check if the UID from a table already exists. I do this for multiple tables with the following public helper function:
methods (Access = public)
function results = checkUID(app,UID,table)
conn = sqlite(app.database); % This is defined as a Property
if table == 'Deployment_Table'
cat = 'Deployment_ID';
elseif table == 'Logger_Table'
cat = 'loggerUID';
elseif table == 'Releaser_Table'
cat = 'releaserUID';
elseif table == 'Satellite_Table'
cat = 'satUID';
else
cat = 'unitID';
end
sqlq = ['SELECT ' cat ' FROM ' table ' WHERE ' cat ' = "' UID '"'];
results =fetch(conn, sqlq);
close(conn)
return
end
end
In general, this works, it allows me to determine if the UID already exists across multiple tables.
I have created a panel, in which I've constructed a form for users to fill out with. There is a button function ('app.SubmitDataButtonPushed') at the bottom of the form, which accesses the data manually entered into the form and organizes it. For this post, it does two things: it generates a deployment ID that needs to be unique (e.g. not in the database) and it references the database to make sure we have records of each piece of equipment (e.g. it should be in the database). This is all done with the checkUID function above.
For the Deployment_ID check the function works as expected. The code is:
function SubmitDataButtonPushed(app, event)
station = app.StationIDDropDown.Value;
depDate = app.DeploymentDateDatePicker.Value;
depDst= datetime(depDate, 'Format','yyyyMMdd');
Deployment_ID = [station '_' char(depDst)];
% Is this deployment already in the database?
dbP =checkUID(app,Deployment_ID, 'Deployment_Table');
if ~isempty(dbP)
uialert(fig, ['Error: Deployment ID ' Deployment_ID ' already exists.'], 'Database Error', "Icon","error");
end
... % More code here
Great. This works both when dbP is and is not empty. If it has data, it triggers the uialert, as intended. However, when I try to modify this code to see if the releaserUID is present, I get the following errors:
... % Continue code here.
% Releaser Check
releaserTypes = app.ModelDropDown_2.Value ; %There are fixed values here.
if releaserTypes == 'LRT (Sonardyne)'
prefix='SD_';
elseif releaserTypes == 'AR-60 (Sub Sea Sonic)'
prefix = 'SSS_';
elseif releaserTypes == 'R500 (Teledyne)'
prefix = 'TD_';
end
releaserID = [prefix, char(app.ReleaseCodeEditField.Value)];
dbR =checkUID(app,releaserID, 'Releaser_Table');
if isempty(dbR)
uialert(fig, ['Error: releaser ID ' releaserID ' is not in database. Add information on releaser to database before adding deployment.'], 'Database Error', "Icon","error");
end
This does not work. It gets hung on the dbR... line. When I run this, specifically stopping on the dbR line to make sure all of the variables are as they should be, I can see nothing out of place. The 'releaserID' variable is produce as a char string, as expected. However, this is the error I get:
Arrays have incompatible sizes for this operation.
Error in DUNA/checkUID (line 101)
if table == 'Deployment_Table'
Error in DUNA/SubmitDataButtonPushed (line 206)
dbR =checkUID(app,releaserID, 'Releaser_Table');
Error in matlab.apps.AppBase>@(source,event)executeCallback(ams,app,callback,requiresEventData,event) (line 62)
newCallback = @(source, event)executeCallback(ams, ...
Related documentation
Error while evaluating Button PrivateButtonPushedFcn.
I have tried this a bunch of different ways. Feeding different variables (LRT vs AR60, etc.). When I run the code manually in Matlab it works. Any ideas what is going on here? I just don't understand why it works with one set of data, and not another.
The table names for the database are correct.
Cheers!
You are using ==
to compare 'chars'
, which should be avoided because it compares them element-wise as arrays.
You can use ==
with "strings"
, but for chars you need to use strcmp( 'abc', 'def' )
So modify your check to something like
if strcmp( tableName, 'Deployment_Table' )
You could also use switch
instead to check multiple cases
switch tableName
case 'Deployment_Table'
cat = 'Deployment_ID';
case 'Logger_Table'
cat = 'loggerUID';
end
I can't run your app, but maybe this wasn't erroring for some of the callback cases because some of the App Designer callbacks were setting tableName
as a string by default, which confusingly works (e.g. "abc" == 'abc'
will compare as if both are strings).
Note that I've also changed your variable name from table
to tableName
because table
is a fairly integral in-built function for the table
data type; by shadowing the name you might cause unexpected errors in future.