Inserting rows
Built-In Procs
JPortal ships with a number of built-in procs to allow easy inserting of data into a database.
Let assume the following table structure in our SI, with various procs defined to insert records:
DATABASE ExampleDatabase
PACKAGE com.example.db
SERVER ExampleServer
SCHEMA ToDoList_App
TABLE ToDoList
ID SEQUENCE
ListName CHAR(255)
ListType SHORT (Private=1, Public=2)
Description CHAR(255)
LastUpdated TIMESTAMP
KEY PKEY PRIMARY
ID
PROC Insert
PROC Insert Returning
PROC BulkInsert
Let's work through the above.
Insert
Insert a new record.
Insert will insert a record into a table.
Adding the RETURNING clause will cause JPortal2 to return the inserted primary key. This is useful when using
database sequences.
--template-generator SQLAlchemy --builtin-generator JavaJCCode
Insert Insert Returning
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67 @dataclass
class DB_ToDoListInsert :
# Enum for ListType field
class ListTypeEnum ( enum . Enum ):
Private = 1
Public = 2
@classmethod
def process_result_value_cls ( cls , value , dialect ):
return DB_ToDoListInsert . ListTypeEnum ( value )
@classmethod
def get_statement ( cls
, ListName : str
, ListType : ListTypeEnum
, Description : str
, LastUpdated : datetime
) -> TextAsFrom :
class _ret :
sequence = "default," #postgres uses default for sequences
output = ""
tail = ""
#session.bind.dialect.name
statement = sa . text (
f "/* PROC ToDoList_App.ToDoList.Insert */"
f "insert into ToDoList_App.ToDoList ("
f " ListName,"
f " ListType,"
f " Description,"
f " LastUpdated"
f " ) "
f " values ("
f " :ListName,"
f " :ListType,"
f " :Description,"
f " :LastUpdated"
f " )" )
text_statement = statement . columns ()
text_statement = text_statement . bindparams ( ListName = ListName ,
ListType = ListType ,
Description = Description ,
LastUpdated = LastUpdated ,
)
return text_statement
@classmethod
def execute ( cls , session : Session , ListName : str
, ListType : ListTypeEnum
, Description : str
, LastUpdated : datetime
) -> None :
params = process_bind_params ( session , [ db_types . NonNullableString ,
sa . types . SmallInteger ,
db_types . NonNullableString ,
sa . types . DateTime ,
], [ ListName ,
ListType . value if isinstance ( ListType , enum . Enum ) else ListType ,
Description ,
LastUpdated ,
])
res = session . execute ( cls . get_statement ( * params ))
res . close ()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79 @dataclass
class DB_ToDoListInsertReturning :
# Enum for ListType field
class ListTypeEnum ( enum . Enum ):
Private = 1
Public = 2
@classmethod
def process_result_value_cls ( cls , value , dialect ):
return DB_ToDoListInsertReturning . ListTypeEnum ( value )
#Outputs
ID : int
@classmethod
def get_statement ( cls
, ListName : str
, ListType : ListTypeEnum
, Description : str
, LastUpdated : datetime
) -> TextAsFrom :
class _ret :
sequence = "default," #postgres uses default for sequences
output = ""
tail = " RETURNING ID" # (1)!
#session.bind.dialect.name
statement = sa . text (
f "/* PROC ToDoList_App.ToDoList.Insert */"
f "insert into ToDoList_App.ToDoList ("
f " ID,"
f " ListName,"
f " ListType,"
f " Description,"
f " LastUpdated"
f " ) "
f " { _ret . output } "
f " values ("
f " { _ret . sequence } "
f " :ListName,"
f " :ListType,"
f " :Description,"
f " :LastUpdated"
f " )"
f " { _ret . tail } " ) # (2)!
text_statement = statement . columns ( ID = sa . types . Integer ,
)
text_statement = text_statement . bindparams ( ListName = ListName ,
ListType = ListType ,
Description = Description ,
LastUpdated = LastUpdated ,
)
return text_statement
@classmethod
def execute ( cls , session : Session , ListName : str
, ListType : ListTypeEnum
, Description : str
, LastUpdated : datetime
) -> Optional [ 'DB_ToDoListInsertReturning' ]:
params = process_bind_params ( session , [ db_types . NonNullableString ,
sa . types . SmallInteger ,
db_types . NonNullableString ,
sa . types . DateTime ,
], [ ListName ,
ListType . value if isinstance ( ListType , enum . Enum ) else ListType ,
Description ,
LastUpdated ,
])
res = session . execute ( cls . get_statement ( * params ))
rec = res . fetchone ()
if rec :
res . close ()
return process_result_rec ( DB_ToDoListInsertReturning , session , [ sa . types . Integer ,
], rec )
return None
Different database engine have different ways of returning records. Postgres requires a postfix or "tail"
which specifies which colunns to return. Here we are setting up the postgres returning section.
Here we inject the Posrgres "tail" we set up above.
Insert Insert Returning
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 public void insert () throws SQLException
{
String statement =
"/* PROC BooksAndAuthors.ToDoList.Insert */"
+ "insert into BooksAndAuthors.ToDoList ("
+ " ListName,"
+ " ListType,"
+ " Description,"
+ " LastUpdated"
+ " ) "
+ " values ("
+ " ?,"
+ " ?,"
+ " ?,"
+ " ?"
+ " )"
;
PreparedStatement prep = connector . prepareStatement ( statement );
lastUpdated = connector . getTimestamp ();
prep . setString ( 1 , listName );
prep . setShort ( 2 , listType );
prep . setString ( 3 , description );
prep . setTimestamp ( 4 , lastUpdated );
prep . executeUpdate ();
prep . close ();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 public boolean insert () throws SQLException
{
Connector . Returning _ret = connector . getReturning ( "ToDoList" , "ID" ); // (1)!
String statement =
"/* PROC BooksAndAuthors.ToDoList.Insert */"
+ "insert into BooksAndAuthors.ToDoList ("
+ " ID,"
+ " ListName,"
+ " ListType,"
+ " Description,"
+ " LastUpdated"
+ " ) "
+ { _ret . output }
+ " values ("
+ { _ret . sequence }
+ " ?,"
+ " ?,"
+ " ?,"
+ " ?"
+ " )"
+ { _ret . tail } // (2)!
;
PreparedStatement prep = connector . prepareStatement ( statement );
lastUpdated = connector . getTimestamp ();
prep . setString ( 1 , listName );
prep . setShort ( 2 , listType );
prep . setString ( 3 , description );
prep . setTimestamp ( 4 , lastUpdated );
ResultSet result = prep . executeQuery ();
if ( ! result . next ())
{
result . close ();
prep . close ();
return false ;
}
id = result . getInt ( 1 );
result . close ();
prep . close ();
return true ;
}
Different database engine have different ways of returning records. Postgres requires a postfix or "tail"
which specifies which colunns to return. Here we are setting up the postgres returning section.
Here we inject the Posrgres "tail" we set up above.
BulkInsert
Insert new records in bulk.
BulkInsert will insert records into a table in bulk.
Adding the <rowcount>
clause will cause JPortal2 to batch the inserts into batches of size .
If <rouwcount>
is omitted, JPortal2 will default to batches of size 1 000.
--template-generator SQLAlchemy --builtin-generator JavaJCCode
Warning
NOT CURRENTLY SUPPORTED IN SQLALCHEMY GENERATOR
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 public void bulkInsert ( List < ToDoList > records ) throws SQLException
{
String statement =
"/* PROC BooksAndAuthors.ToDoList.BulkInsert */"
+ "insert into BooksAndAuthors.ToDoList ("
+ " ListName,"
+ " ListType,"
+ " Description,"
+ " LastUpdated"
+ " ) "
+ " values ("
+ " ?,"
+ " ?,"
+ " ?,"
+ " ?"
+ " )"
;
for ( int batchSize = 0 ; batchSize <= Math . ceil ( records . size () / 1000 ); batchSize ++ ) {
PreparedStatement prep = connector . prepareStatement ( statement );
for ( int recCount = ( batchSize * 1000 ); recCount < ( batchSize + 1 ) * 1000 && recCount < records . size (); recCount ++ ) {
ToDoList record = records . get ( recCount );
lastUpdated = connector . getTimestamp ();
prep . setString ( 1 , record . listName );
prep . setShort ( 2 , record . listType );
prep . setString ( 3 , record . description );
prep . setTimestamp ( 4 , lastUpdated );
prep . addBatch ();
}
prep . executeBatch ();
prep . close ();
}
}