Using CodenameOne web database extension, I can get basic SQL fields to work for strings and numbers, but not for large binary objects BLOBs. I'm following the instructions here: https://www.codenameone.com/blog/connecting-to-a-mysql-database-part-2.html
Are BLOBs supported by CodenameOne? If so how do you do it? I can't find any examples that use BLOB types.
I've tried using long strings, and with the MarianaDB, can get up to 512K string size, but I need to store images which can be larger.
MariaDB [(none)]> use tsg; desc photos;
Database changed
+------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| player_id | int(11) | NO | | NULL | |
| tree_id | int(11) | NO | | NULL | |
| photo_type | longtext | NO | | NULL | |
| image | blob | YES | | NULL | |
+------------+------------------+------+-----+---------+----------------+
5 rows in set (0.001 sec)
When I add the record without the blob it works:
m.put("playerId", "1");
m.put("treeId", "2");
m.put("photoType", "front");
m.put("image", null);
client.create(m, res -> {
System.out.println(m);
System.out.println("create result = " + res);
});
outputs:
{treeId=2, image=null, photoType=front, playerId=1}
create result = true
But when I try to add the blob, it does not:
m.put("playerId", "1");
m.put("treeId", "2");
m.put("photoType", "front");
byte bytes[] = new byte[100];
m.put("image", bytes);
client.create(m, res -> {
System.out.println(m);
System.out.println("create result = " + res);
});
outputs:
{treeId=2, image=[B#5968c8cb, photoType=front, playerId=1}
create result = false
Help! I'm using BLOBs in the wrong way, or does CN1 not support BLOBs?
The only error message is from the result of create being false.
It doesn't have builtin support for that at this time. You can use MultipartRequest to submit binary data to the server.
I have a Access DB with following scheme:
+---------+---------+-----------+------------+-------------------------------------------+
| BrandNr | TextNr | LangCode | OngoingNr | Text |
+---------+---------+-----------+------------+-------------------------------------------+
| 1 | AB | 1 | 1 | Text beginns here but it doesn't end here |
| 1 | AB | 1 | 2 | Text isn't finished so need second row |
| 1 | AC | 2 | 1 | New text |
| 2 | hg2 | 1 | 1 | New brand new text |
+---------+---------+-----------+------------+-------------------------------------------+
Now I need to merge the text where BrandNR, TextNr and LangCode are the same. The Text should be ordered by the OngoingNr.
Some ideas?
I believe this will require VBA.
One possible method is to call a VBA function which defines a Static string-type variable that is initialised to an empty string for every new combination of BrandNR, TextNr and LangCode, else concatenated with itself.
Open the VBA IDE using Alt+F11
Insert a new Public Module Alt+I,M
Copy the following basic code into the new Module:
Function Concat(strInp As String, lngOrd As Long) As String
Static strTmp As String
If lngOrd = 1 Then strTmp = strInp Else strTmp = strTmp & " " & strInp
Concat = strTmp
End Function
In MS Access, create a new query with the following SQL, changing MyTable to the name of your table:
select q.BrandNr, q.TextNr, q.LangCode, Concat(q.Text,q.OngoingNr) as Merged
from
(
select t.* from MyTable t
order by t.BrandNr, t.TextNr, t.LangCode, t.OngoingNr
) q
I've got a simple MySQL table, which contains an "Age" column with integer and null values.
Customers
+--------------+--------------+ .... +------------+
| Name | Location | | Age |
+--------------+--------------+ .... +------------+
| Murphy | US | | 23 |
| Pierre | France | | 42 |
| Rafael | Spain | | null |
| Paulo | Italy | | 21 |
+--------------+--------------+ .... +------------+
Name and Location are type varChar and Age is type int.
However when I attempt to read from it in my VB.net code...
Dim connStr as string = Session("connectionString") 'My Connection String'
Dim sql As String = "SELECT * FROM Customers;"
Dim conn As MySqlConnection = New MySqlConnection(connStr)
conn.Open()
Dim da As MySqlDataAdapter = New MySqlDataAdapter(sql , conn)
Dim ds as new dataset
da.Fill(ds)
... the Age column in the dataset ds has System.Byte[] in every cell instead of the integer value.
Why is this happening?
Try to make sure that Age column only returns integer values.
Change your select to
SELECT Name,Location,IFNULL(Age,0) AS Age FROM Customers;
Another check, does your dataset allow dbnull? There is a property you can change. Maybe give that a try also with your inital SELECT * FROM Customers;
I have table with two columns (varchar from, varchar to). This table represents connections betwen nodes (from node, to node). I want to get all nodes connected from or to node that I specify and nodes connected from or to those nodes. Currently I use query below that gives me proper results but I'm searching for neater solution.
//currently used query specified node "node1"
SELECT tonode as node
FROM conn
WHERE
fromnode
IN
(SELECT tonode as node FROM conn WHERE fromnode="node1"
UNION
SELECT fromnode as node FROM conn WHERE tonode="node1")
UNION
SELECT fromnode as node
FROM conn
WHERE
tonode
IN
(SELECT tonode as node FROM conn WHERE fromnode="node1"
UNION
SELECT fromnode as node FROM conn WHERE tonode="node1")
//create table for conn table
CREATE TABLE `conn` (
`fromnode` varchar(70) NOT NULL,
`tonode` varchar(70) NOT NULL,
PRIMARY KEY (`fromnode`,`tonode`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
INSERT INTO `conn` (`fromnode`,`tonode`) VALUES
('node1','node2'),
('node1','node3'),
('node3','node2'),
('node4','node1'),
('node4','node2'),
('node4','node5'),
('node5','node6'),
('node4','node3');
My optimized version:
SET #origin = "node1";
SELECT DISTINCT
IF(c1.fromnode = #origin,
IF(c1.tonode = c2.tonode,
IF(c2.fromnode = #origin, c2.tonode, c2.fromnode),
IF(c2.tonode = #origin, c2.fromnode, c2.tonode)
),
IF(c1.fromnode = c2.tonode,
IF(c2.fromnode = #origin, c2.tonode, c2.fromnode),
IF(c2.tonode = #origin, c2.fromnode, c2.tonode)
)
) AS node
FROM conn AS c1
LEFT JOIN conn AS c2 ON (c1.fromnode = c2.fromnode OR c1.tonode = c2.fromnode OR c1.fromnode = c2.tonode OR c1.tonode = c2.tonode)
WHERE c1.fromnode = #origin OR c1.tonode = #origin;
the DESCRIBE output of your old query:
+----+--------------------+------------+--------+---------------+---------+---------+------------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+------------+--------+---------------+---------+---------+------------+------+--------------------------+
| 1 | PRIMARY | conn | index | NULL | PRIMARY | 424 | NULL | 8 | Using where; Using index |
| 2 | DEPENDENT SUBQUERY | conn | eq_ref | PRIMARY | PRIMARY | 424 | const,func | 1 | Using where; Using index |
| 3 | DEPENDENT UNION | conn | eq_ref | PRIMARY | PRIMARY | 424 | func,const | 1 | Using where; Using index |
| NULL | UNION RESULT | <union2,3> | ALL | NULL | NULL | NULL | NULL | NULL | |
| 4 | UNION | conn | index | NULL | PRIMARY | 424 | NULL | 8 | Using where; Using index |
| 5 | DEPENDENT SUBQUERY | conn | eq_ref | PRIMARY | PRIMARY | 424 | const,func | 1 | Using where; Using index |
| 6 | DEPENDENT UNION | conn | eq_ref | PRIMARY | PRIMARY | 424 | func,const | 1 | Using where; Using index |
| NULL | UNION RESULT | <union5,6> | ALL | NULL | NULL | NULL | NULL | NULL | |
| NULL | UNION RESULT | <union1,4> | ALL | NULL | NULL | NULL | NULL | NULL | |
+----+--------------------+------------+--------+---------------+---------+---------+------------+------+--------------------------+
the DESCRIBE output of my query:
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------------------------------------+
| 1 | SIMPLE | c1 | index | PRIMARY | PRIMARY | 424 | NULL | 8 | Using where; Using index; Using temporary |
| 1 | SIMPLE | c2 | index | PRIMARY | PRIMARY | 424 | NULL | 8 | Using index |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------------------------------------+
if I understood you correctly (about going only 2 levels deep), you can do something like this:
SELECT level,fromnode , tonode
FROM conn1
WHERE level < 3
CONNECT BY PRIOR tonode = fromnode
START WITH fromnode like '%';
With these "from" and "to" relationships being bidirectional (you are needing to traverse both directions), there's just no easy statement to do that in MySQL. To get all of the node values in a single result set returned in a single column, the closest I can come to avoiding a UNION operation is:
SELECT CASE
WHEN t.i = 1 THEN t.dnode
WHEN t.i = 2 AND t.dnode = c.fromnode THEN c.tonode
WHEN t.i = 2 AND t.dnode = c.tonode THEN c.fromnode
ELSE NULL
END AS node
FROM ( SELECT d.i
, m.root
, CASE WHEN m.root = n.fromnode THEN n.tonode ELSE n.fromnode END AS dnode
FROM (SELECT 'node1' AS root) m
CROSS
JOIN (SELECT 1 AS i UNION ALL SELECT 2) d
LEFT
JOIN conn n ON m.root IN (n.fromnode,n.tonode)
) t
LEFT
JOIN conn c
ON t.i = 2 AND t.dnode IN (c.fromnode,c.tonode)
GROUP BY node
ORDER BY node
I don't know if I'm even going to be able to unpack that, but I'll try.
To avoid having to specify the root node 'node1' multiple times, I use a subquery to return it.
(SELECT 'node1' AS root) m
Because we are going "two levels deep", I need two sets of nodes, so I create a Cartesian product to double the number of rows I've got, and I'm going to label them 1 for the first level, and 2 for the second level.
CROSS
JOIN (SELECT 1 AS i UNION ALL SELECT 2) d
With that, I'm now ready to join to the conn table, and I want any rows that have either a fromnode or tonode value that matches the root node.
LEFT
JOIN conn n ON m.root IN (n.fromnode,n.tonode)
With that resultset, I want to "flip" the fromnode and tonode on some of those rows so that we basically always have the "root" node on one side. I do this with a CASE expression that tests which side matches the root:
CASE WHEN m.root = n.fromnode THEN n.tonode ELSE n.fromnode END AS dnode
So now I wrap that resultset as an inline view aliased t. That subquery can be run separately, to see that we're returning what we expect:
SELECT d.i
, m.root
, CASE WHEN m.root = n.fromnode THEN n.tonode ELSE n.fromnode END AS dnode
FROM (SELECT 'node1' AS root) m
CROSS
JOIN (SELECT 1 AS i UNION ALL SELECT 2) d
LEFT
JOIN conn n ON m.root IN (n.fromnode,n.tonode)
We do need to return that "level" value (d.i we generated earlier, we need it on the next step, when we join to the conn table again, to traverse the next level, and I only need to join those rows where we are going to look at the second level.
LEFT
JOIN conn c
ON t.i = 2 AND t.dnode IN (c.fromnode,c.tonode)
And again, I don't care which side node is on, at this point, I just need to do the match.
At this point, you could run the whole query, and pull t.*, c.* to see what we've got, but I'm going to skip that part and go right to the "magic".
At this point, we can use a CASE expression to "pick out" the node value we want from that mess.
If the level value (unfortunately labeled i) is a 1, then we're looking at the first level, so we just need to get the "nodeX" value that was on the "other" side of the "root". That's available from the t source as expression aliased as dnode.
Otherwise, we're going to look at the rows for the "second" level, i = 2. (In this particular case, the test on i = 2 could be omitted, but it's included hear for completeness, and just in case we are going to extend this approach to get three (gasp!) or more (oh my!) levels.
Here, we need to know which side (from or to) matched the first level, and we just pull the other side. If t.dnode matches on side, we pull the other side.
Finally, we use a GROUP BY to collapse the duplicates.
Since we don't care what level these were from, we omit returning t.i, which would give us the level.
SUMMARY
I don't think this is any more straightforward than your query. And I have no idea how performance would compare. But it's nice to have other statements to compare performance against.
i am connecting to a mysql table through vba in excel and i am updating it:
Set cn = New ADODB.Connection
cn.Open "DRIVER={MySQL ODBC 5.1 Driver};" & _
"SERVER=localhost;" & _
"DATABASE=employees;" & _
"USER=root;" & _
"PASSWORD=M1llen;" & _
"Option=3"
'lets get the batch info
'
' open a recordset
Set rs = New ADODB.Recordset
rs.Open "batchinfo", cn, adOpenKeyset, adLockOptimistic, adCmdTable
' all records in a table from Report 1
'Set wsSheet1 = wbBook.Worksheets(1)
' better refer by name
'Set wsSheet1 = wbBook.Worksheets.("Report 1")
Worksheets.Item("Report 1").Select
dpath = Range("B2").Text
atime = Trim(Range("B3").Text)
rtime = Trim(Range("B4").Text)
lcalib = Trim(Range("B5").Text)
aname = Trim(Range("B6").Text)
rname = Trim(Range("B7").Text)
bstate = Trim(Range("B8").Text)
instrument = GetInstrFromXML()
With rs
.AddNew ' create a new record
' add values to each field in the record
.Fields("datapath") = "abc"
.Fields("analysistime") = atime
.Fields("reporttime") = rtime
.Fields("lastcalib") = lcalib
.Fields("analystname") = aname
.Fields("reportname") = rname
.Fields("batchstate") = bstate
.Fields("instrument") = instrument
.Update ' stores the new record
End With
the issue is that the only field that gets updated is the instrument field!!
here i a desc of the batchinfo table mysql:
mysql> desc batchinfo;
+--------------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+---------+------+-----+---------+----------------+
| rowid | int(11) | NO | PRI | NULL | auto_increment |
| datapath | text | YES | | NULL | |
| analysistime | text | YES | | NULL | |
| reporttime | text | YES | | NULL | |
| lastcalib | text | YES | | NULL | |
| analystname | text | YES | | NULL | |
| reportname | text | YES | | NULL | |
| batchstate | text | YES | | NULL | |
| instrument | text | YES | | NULL | |
+--------------+---------+------+-----+---------+----------------+
9 rows in set (0.00 sec)
funny thing is that when i recreate the table without the auto_increment then it works fine
i really need someone to answer this question, i dont care if you have a hunch or not exactly sure, i will try any solution
I'm not familiar with MySQL but TEXT looks like a blob type? If so I'm surprised it works at all as ADO requires special handling for BLOBS ( http://dev.mysql.com/tech-resources/articles/vb-blob-handling.html )
Try a VARCHAR type instead.
You could also try ADOCn.Execute "INSERT ..."