I use CockroachDb and Npgsql driver.
I have a simple Users table. When I insert new record, every other query fails with syntax error, which seems bizarre to me.
CREATE TABLE Users (
RequestIdentifier BYTEA NOT NULL UNIQUE,
Identifier UUID PRIMARY KEY DEFAULT gen_random_uuid(),
Id INT8 NOT NULL DEFAULT unique_rowid(),
Email BYTEA NOT NULL UNIQUE,
Username BYTEA NOT NULL,
PasswordHash BYTEA NOT NULL
);
var q = #"
INSERT INTO Users (RequestIdentifier, Email, Username, PasswordHash)
VALUES (#RequestIdentifier, #Email, #Username, #PasswordHash)
ON CONFLICT (RequestIdentifier)
DO NOTHING
RETURNING Identifier
";
byte[] userIdentifier = null;
using (var cmd = new NpgsqlCommand(q, dbConn)) {
cmd.Parameters.Add("RequestIdentifier", NpgsqlDbType.Bytea);
cmd.Parameters.Add("Email", NpgsqlDbType.Bytea);
cmd.Parameters.Add("Username", NpgsqlDbType.Bytea);
cmd.Parameters.Add("PasswordHash", NpgsqlDbType.Bytea);
await cmd.PrepareAsync();
cmd.Parameters[0].Value = msg.RequestIdentifier;
cmd.Parameters[1].Value = msg.Email;
cmd.Parameters[2].Value = msg.Username;
cmd.Parameters[3].Value = passwordHash;
try {
userIdentifier = ((Guid) await cmd.ExecuteScalarAsync()).ToByteArray();
} catch (PostgresException e) when (e.SqlState == SqlErrorCodes.UniqueViolation) {
logger.Information("Email {Email} already in use", UTF8.GetString(msg.Email));
} catch (PostgresException e) {
logger.Error("{Exception}", e);
throw;
}
}
Npgsql.PostgresException (0x80004005): 42601: at or near "close": syntax error
at Npgsql.NpgsqlConnector.<>c__DisplayClass160_0.<<DoReadMessage>g__ReadMessageLong|0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at Npgsql.NpgsqlConnector.<>c__DisplayClass160_0.<<DoReadMessage>g__ReadMessageLong|0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at Npgsql.NpgsqlConnector.<>c__DisplayClass160_0.<<DoReadMessage>g__ReadMessageLong|0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at Npgsql.NpgsqlDataReader.NextResult(Boolean async, Boolean isConsuming)
at Npgsql.NpgsqlCommand.ExecuteReaderAsync(CommandBehavior behavior, Boolean async, CancellationToken cancellationToken)
at Npgsql.NpgsqlCommand.ExecuteScalar(Boolean async, CancellationToken cancellationToken)
at OwlAuthentication.Services.CockroachDbStorageService.CreateOrRetrieveExistingUser(SignUpMessage msg) in C:\Users\Che Khen Kho\Desktop\dotnet\OwlAuthentication\Services\CockroachDbStorageService.cs:line 94
Exception data:
Severity: ERROR
SqlState: 42601
MessageText: at or near "close": syntax error
Detail: source SQL:
CLOSE ALL
^
File: lexer.go
Line: 175
Routine: Error
If I try, say, 10 queries, 5 of them would fail with this exception, but quite often more than 5 rows would actually get inserted (sometimes 6, sometimes 8, etc.).
I tested it with PostgreSQL as well (using uuid_generate_v4 instead of gen_random_uuid and BIGSERIAL for Id column), and everything works fine.
I think this is covered by this issue (https://github.com/cockroachdb/cockroach/issues/45490) which is fixed in CockroachDB v20.1
Related
I am trying to insert a new note into a database with the following flutter code. final noteId = await db.insert(noteTable, { userIDColumn: owner.id, textColumn: text, isSyncedWithCloudColumn: 1, });
I get the following exception Exception has occurred. SqfliteDatabaseException (DatabaseException(NOT NULL constraint failed: note.id (code 1299 SQLITE_CONSTRAINT_NOTNULL)) sql 'INSERT INTO note (user_id, text, is_synced_with_cloud) VALUES (?, ?, ?)' args [1, , 1])
I tried the code described above and got the exception instead of a successful result.
Dapper does not catch error when I try and insert a duplicate record. It however populates the first record of the result with the error message. E.g.
try
{
var result = Dapper.SqlMapper.Query(SCADConn, sql, d, null, true, 30, ct);
return result;
}
catch (Exception e)
{
throw (e);
}
When I run the above code the result variable contains a record with a count of 1 row with the following DapperRow
{{DapperRow, ErrorNumber = '2601', ErrorSeverity = '14', ErrorState = '1', ErrorProcedure = 'OrganizationAdd', ErrorLine = '55', ErrorMessage = 'Cannot insert duplicate key row in object 'dbo.Organization' with unique index 'IX_Organization_1'. The duplicate key value is (AAA Purchasing Pty (Ltd), 123123123123).'}}
What a stupid mistake. I returned a record with the error in stored proc error handling.
I'm creating an insurance management system for my DBMS project in university, and I am having a problem with deleting a record from SQL Server. It throws an exception:
SqlException: com.microsoft.sqlserver.jdbc.SQLServerException: The statement did not return a result set.
It also successfully deleted a record from my database. Could anyone please tell me how to remove this kind of exception?
String SQL="delete from INMS_3 where Agent_Id=? and First_Name=? and Last_Name=? and User_Name=? and Phone_no=?";
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
String connectionUrl = "jdbc:sqlserver://localhost:1433;" +
"databaseName=INMS;user=TestingUser;password=1234;";
Connection con = DriverManager.getConnection(connectionUrl);
System.out.println("Connected to sql server");
String str=jTextField1.getText();
String str1=jTextField2.getText();
String str2=jTextField3.getText();
String str3=jTextField4.getText();
String str4=jTextField5.getText();
PreparedStatement st = con.prepareStatement(SQL);
st.setString(1, str);
st.setString(2,str1);
st.setString(3,str2);
st.setString(4,str3);
st.setString(5, str4);
ResultSet rs = st.executeQuery();
if(rs.next());
{
JOptionPane.showMessageDialog(null,"Deleted Succesfully");
}
if(!rs.next())
{
JOptionPane.showMessageDialog(null,"Unable to delete");
}
else
{
JOptionPane.showMessageDialog(null,"Unable to delete");
}
} catch (SQLException e) {
System.out.println("SQL Exception: "+ e.toString());
} catch (ClassNotFoundException cE) {
System.out.println("Class Not Found Exception: "+ cE.toString());
}
I think you are using the wrong thing to perform the delete operation.
Try using st.executeUpdate() instead of ResultSet rs = st.executeQuery() - you are executing a delete rather than something that would return a result set.
This is not a problem with SQL Server. The problem is with your code (what is that? C#? The object is set to expect a result set from the server, but the query is a DELETE statement, and those return no rows... ever.
State the programing language, and research for how to execute statement instead requesting result sets.
This line makes sense for a SELECT not for an UPDATE
ResultSet rs = st.executeQuery();
if you're executing a delete statement, why are you executing
ResultSet rs = st.executeQuery();
Here's a sample c# ado.net. concept it the same if you're using java.
using(var conn = new SqlConnection("my connection string"))
{
var deleteCmd = new SqlCommand();
deleteCmd.Connection = conn;
deleteCmd.CommandType = CommandType.Text;
deleteCmd.CommandText = #"
DELETE Accounts
WHERE account_id = #p_account_id
";
deleteCmd.Parameters.AddWithValue("p_account_id", 123);
conn.Open();
deleteCmd.ExecuteNonQuery();
}
Can someone explain to me how to write a test class for an apex trigger like the following one?
trigger LeadAssignmentTrigger on Broker__c (before insert,before update)
{
List<Broker__c > leadsToUpdate = new List<Broker__c >();
for (Broker__c broker: Trigger.new)
{
if (broker.Referral_ID__c!= NULL)
{
String str = broker.Referral_ID__c;
Integer ln = str.Length();
String likeStr = '%'+str.subString(ln-10, ln-7)+'%'+str.subString(ln-7, ln-4) +'%'+ str.subString(ln-4);
// Find the sales rep for the current zip code
List<User> zip = [select Id from User
where MobilePhone Like : likeStr];
// if you found one
if (zip.size() > 0)
{
//assign the lead owner to the zip code owner
broker.OwnerId = zip[0].Id;
leadsToUpdate.add(broker);
}
else
{
// Throw Error
broker.addError('Invalid Referrel ID');
}
}
}
}
I am new to salesforce.Anyone help me to how to write apex class(test class) for above trigger.
#isTest
private class LeadAssignmentTriggerTest
{
static testMethod void validateHelloWorld()
{
User userObj = new User( Id = UserInfo.getUserId() );
userObj.MobilePhone = '5555555555';
update userObj
test.startTest();
try
{
Broker__c broker = new Broker__c();
broker.Referral_ID__c = '55555555';
broker.City ='New York';
// Add all required field here
insert broker;
}
Catch(Exception ee)
{
}
test.stopTest();
}
}
AccountBrowseExtensionTesttestAccountBrowseSystem.DmlException: Insert failed. First exception on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, City is mandatory: []
Stack Trace: Class.AccountBrowseExtensionTest.testAccountBrowse: line 20, column 1
CloseActivityControllerTesttestCloseActivitySystem.DmlException: Insert failed. First exception on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, City is mandatory: []
Stack Trace: Class.CloseActivityControllerTest.testCloseActivity: line 13, column 1
changeOwnerControllerTesttestchangeOwnerSystem.DmlException: Insert failed. First exception on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, City is mandatory: []
Stack Trace: Class.changeOwnerControllerTest.testchangeOwner: line 20, column 1
cntactsclassTesttestcntactsSystem.DmlException: Insert failed. First exception on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, City is mandatory: []
Stack Trace: Class.cntactsclassTest.testcntacts: line 13, column 1
LogACallControllerTesttestLogACallSystem.DmlException: Insert failed. First exception on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, City is mandatory: []
Stack Trace: Class.LogACallControllerTest.testLogACall: line 14, column 1
RedirectControllerTesttestRedirectSystem.DmlException: Insert failed. First exception on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, City is mandatory: []
Stack Trace: Class.RedirectControllerTest.testRedirect: line 20, column 1
TestAccountSharetestSystem.DmlException: Insert failed. First exception on row 0; first error: FIELD_CUSTOM_VALIDATION_EXCEPTION, Mobile Number is mandatory after Appointment is fixed.: []
Stack Trace: Class.TestAccountShare.test: line 40, column 1
You are writing a trigger for Broker__c on before insert and before update
So since it's a trigger, your code will run every time you insert or update a record.
To write a test class simply create two test methods:
one to insert a Broker__c record
one to update a Broker__c record
Check here on how to create test classes
By the way you should check the best coding practices on how to write a better trigger and handlers here
Edit:
You should also remove the SOQL inside the loop and create a Map with your query outside the for loop
I want to use transactions on multiple insert/update query for multiple model/table.
In cakephp3 documentation have an example of transaction using connection manager execute() method but I have to use transaction with save() method of cakephp3. I tried it using save() method but it didn't work. There was a SQL error, it execute all query and saving data except the query where the sql error have, rollback didn't work!
my code was like-
$connection = ConnectionManager::get('default');
$connection->transactional(function ($connection) use($inputs, $status) {
$serviceTbl = $this->Service;
$service = $serviceTbl->newEntity();
$service->name = $inputs['name'];
$service = $serviceTbl->save($service);
if($service)
{
$this->loadModel('SrvApiClientInfo');
$SrvApiClientInfo = $this->SrvApiClientInfo;
$SrvApiClient = $SrvApiClientInfo->newEntity();
$SrvApiClient->client_name = $inputs['basic_info']['client_name'];
$SrvApiClient->organization_name = $inputs['basic_info']['vendor_name'];
$SrvApiClient->address = $inputs['basic_info']['address'];
$SrvApiClient->email = $inputs['basic_info']['email'];
$SrvApiClient->mobile = $inputs['basic_info']['mobile'];
$SrvApiClient->phone = $inputs['basic_info']['phone'];
$SrvApiClient->fax = $inputs['basic_info']['fax'];
$SrvApiClient->emergency_contact_name = $inputs['basic_info']['emergency_contact_name'];
$SrvApiClient->emergency_contact_mobile = $inputs['basic_info']['emergency_contact_mobile'];
$SrvApiClient->emergency_contact_designation = $inputs['basic_info']['emergency_contact_designation'];
$SrvApiClient = $SrvApiClientInfo->save($SrvApiClient);
if($SrvApiClient){
$this->loadModel('ServiceApiRegistration');
$tblServiceApiRegistration = $this->ServiceApiRegistration;
foreach($inputs['method'] as $method)
{
$ServiceApiRegistration = $tblServiceApiRegistration->newEntity();
$ServiceApiRegistration->service_id = $service['service_id'];
$ServiceApiRegistration->service_api_id = $method;
$ServiceApiRegistration->client_id = $SrvApiClient['client_id'];
$ServiceApiRegistration->status_id = $status['Inactive'];
$tblServiceApiRegistration->save($ServiceApiRegistration);
}
}
}
});
Check the docs that you've linked a little more closely, especially point 3 and 4 of the "The transactional method will do the following" list
The transactional method will do the following:
[...]
If the closure raises an exception, a rollback will be issued. The original exception will be re-thrown.
If the closure returns false, a rollback will be issued.
Your code neither returns false, nor does it throw an exception when something goes wrong, hence no rollback will be issued.
If there really was an SQL "error", ie an exception triggered in the core, then it should have been catched by the transaction wrapper, and a rollback should have been issued. So I'd suspect that either, there was no exception, or that rollbacks aren't supported or the driver thinks they aren't.