First of all, the following statement shall raise an error.
INSERT INTO USUARIOS (ID
, MATRICULA
, NOME
, SENHA
, NIVEL
, MALETA
, EMAIL
) VALUES ( 'select id_usuarios.NEXTVAL from dual'
, 'TESTE'
, 'Frederico'
, 'TESTE'
, '1'
, '7000'
, 'daerro@erro.com.br'
)
The major error in this insert statement is that you try to insert a string into a number field. ID
as an integer will never accept 'select id_usuarios.NEXTVAL FROM dual'
because you actually try to insert the 'select id_usuarios.NEXTVAL FROM dual'
as being the actual value.
Should you wish to insert the sequence next value into your ID field, try the following:
INSERT INTO USUARIOS (ID
, MATRICULA
, NOME
, SENHA
, NIVEL
, MALETA
, EMAIL
) ( SELECT id_usuarios.NEXTVAL
, 'TESTE'
, 'Frederico'
, 'TESTE'
, 1
, 7000
, 'daerro@erro.com.br'
FROM DUAL
)
Second. both your NIVEL
and MALETA
fields seem to be numbers as well, so remove the apostrophes!
Third, it is best to let Oracle handle its sequence itself. The best practice for autoincremental fields using Oracle is to write a trigger on insert
which will actually select the next sequence value and put it right where it belongs. Plus, notice that if you want to insert a selected value, then you must use an INSERT SELECT
statemement, not an INSERT VALUE
statement.
Fourth, using string.Format
method is really, really, really not a good idea at all as it will let room for SQL Injection. Instead, use have to use command parameters. In addition to it, try to use Using Blocks as they shall dispose any no more required resources when out of scope.
using (var cnx = new OleDbConnection(connectionString)) {
var sql =
@"insert into usuarios(matricula, nome, sehna, nivel, maleta, email)
values (@matricula, @nome, @sehna, @nivel, @maleta, @email)";
using (var cmd = new OleDbCommand(sql, cnx)) {
cnx.Open();
cmd.Parameters.AddWithValue("@matricula", txt_matricula.Text);
cmd.Parameters.AddWithValue("@nome", txt_nome.Text);
cmd.Parameters.AddWithValue("@sehna", txt_senha.Text);
cmd.Parameters.AddWithValue("@nivel", int.Parse(DropDownList_nivel.Text));
cmd.Parameters.AddWithValue("@maleta", int.Parse(txt_maleta.Text));
cmd.Parameters.AddWithValue("@email", txt_email.Text);
try { cmd.ExecuteNonQuery(); }
catch { }
finally { if(cnx.State == ConnectionState.Open) cnx.Close(); }
}
}
Fifth, it is important to call the right method for the job.
DbCommand.ExecuteNonQuery
Method used for DELETE
, INSERT
and UPDATE
statements ONLY.
DbCommand.ExecuteReader
Method used for SELECT
statements with multiple rows and columns.
DbCommand.ExecuteScalar
Method used when the expected result or the only important value shall be located in the first column of the first row. Any other rows and columns than the first shall be ignored.
See my answers to these related questions:
EDIT
I tried giving a hand before a select to retrieve the ID (select id_usuarios.NEXTVAL from dual ) and then retrieve ID already passed the insert
Here's how I'd go about it.
First, create the trigger on your table.
create or replace trigger increment_usuarios_id
before insert on usuarios
for each row
begin
if :new.id is null then
select id_usuarios.nextval into :new.id from dual;
end if;
end;
Then, when inserting into the usuarios
data table, the ID
column shall get fed automatically by the increment_usuarios_id
trigger.
Hence one is now able to insert without taking any special care on the identity.
insert into usuarios (
matricula
, nome
, sehna
, nivel
, maleta
, email
) values (
'TESTE'
, 'Frederico'
, 'TESTE'
, 1
, 7000
, 'daerror@error.com.br'
);
commit;
You then shall see your new user into the table as expected. If this works, then take the same insert statement
and make it the value of your sql
variable within your C# code, not forgetting to replace values with the actual control values from your GUI.