查询结果:
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')
protected void btn_incluir_Click(object sender,EventArgs e) {
OleDbConnection cnx = new OleDbConnection(new AdministradorDAO().conexao);
cnx.Open();
string seq = ("select id_usuarios.NEXTVAL from dual");
OleDbCommand cmdo = new OleDbCommand(seq, cnx);
cmdo.ExecuteNonQuery();
//string sqltxt = "INSERT INTO USUARIOS (ID,MATRICULA,NOME,SENHA,NIVEL,MALETA,EMAIL) VALUES (ID_USUARIOS.NextVal,'MATRICULA','NOME','SENHA','NIVEL',MALETA,'EMAIL')";
string sqltxt = string.Format(
@"INSERT INTO USUARIOS ( ID
, MATRICULA
, NOME
, SENHA
, NIVEL
, MALETA
, EMAIL
) VALUES ( '{0}', '{1}', '{2}', '{3}', '{4}', '{5}', '{6}')"
, seq, txt_matricula.Text, txt_nome.Text, txt_senha.Text
, DropDownList_nivel.Text, txt_maleta.Text, txt_email.Text);
OleDbCommand cmd = new OleDbCommand(sqltxt, cnx);
cmd.ExecuteNonQuery();
txt_matricula.Text = "";
txt_nome.Text = "";
txt_senha.Text = "";
DropDownList_nivel.Text = "";
txt_maleta.Text = "";
txt_email.Text = "";
carregaUsuarios();
}
答案 0 :(得分:1)
首先,以下陈述将引发错误。
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'
)
此insert语句中的主要错误是您尝试将字符串插入到数字字段中。 ID
作为整数永远不会接受'select id_usuarios.NEXTVAL FROM dual'
,因为您实际上尝试将'select id_usuarios.NEXTVAL FROM dual'
作为实际值插入。
如果您希望将序列下一个值插入ID字段,请尝试以下操作:
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
)
二。您的NIVEL
和MALETA
字段似乎也都是数字,因此请删除撇号!
第三,最好让Oracle自己处理它的序列。使用Oracle的自动增量字段的最佳实践是编写trigger on insert
,它将实际选择下一个序列值并将其放在它所属的位置。另外,请注意,如果要插入所选值,则必须使用INSERT SELECT
statemement,而不是INSERT VALUE
语句。
第四,使用string.Format
方法确实非常非常好,因为它会为SQL Injection留出空间。相反,使用必须使用命令参数。除此之外,请尝试使用Using Blocks,因为当超出范围时,他们将处置任何不再需要的资源。
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(); }
}
}
第五,为工作调用正确的方法很重要。
<强> DbCommand.ExecuteNonQuery 强>
仅用于DELETE
,INSERT
和UPDATE
语句的方法。
<强> DbCommand.ExecuteReader 强>
用于具有多行和多列的SELECT
语句的方法。
<强> DbCommand.ExecuteScalar 强>
当预期结果或唯一重要值应位于第一行的第一列时使用的方法。应忽略除第一行之外的任何其他行和列。
请参阅我对这些相关问题的回答:
修改强>
我尝试在选择之前伸出一只手来检索ID(从双重中选择id_usuarios.NEXTVAL),然后检索已通过插入的ID
以下是我如何去做。
首先,在桌面上创建触发器。
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;
然后,当插入usuarios
数据表时,ID
列将由increment_usuarios_id
触发器自动投放。
因此,现在可以在不对身份进行任何特别注意的情况下插入。
insert into usuarios (
matricula
, nome
, sehna
, nivel
, maleta
, email
) values (
'TESTE'
, 'Frederico'
, 'TESTE'
, 1
, 7000
, 'daerror@error.com.br'
);
commit;
然后,您将按预期看到新用户进入表格。如果这样可行,那么请使用相同的insert statement
并将其设置为C#代码中sql
变量的值,而不要忘记使用GUI中的实际控制值替换值。
答案 1 :(得分:0)
看看这个:link
OleDbConnection cnx = new OleDbConnection(new AdministradorDAO().conexao);
cnx.Open();
string seq = ("select id_usuarios.NEXTVAL from dual");
OleDbCommand cmdo = new OleDbCommand(seq, cnx);
int id= (int)cmdo.ExecuteScalar();
using (OleDbCommand cmd = cnx.CreateCommand())
{
// create command with placeholders
cmd.CommandText =
"INSERT INTO USUARIOS"+
"([ID], [MATRICULA], [NOME], [SENHA], [NIVEL],[MALETA],[EMAIL]) "+
"VALUES(@id, @ma, @no, @se, @ni,@ma,@em)";
// add named parameters
cmd.Parameters.AddRange(new OleDbParameter[]
{
new OleDbParameter("@id", id),
new OleDbParameter("@ma", txt_matricula.Text),
...
};
cmd.ExecuteNonQuery();
}
将OleDbCommand中的实际硬编码参数替换为占位符(前缀为@), b)将OleDbParameter的实例添加到DbCommand.Parameters属性。参数名称必须与占位符名称匹配。
答案 2 :(得分:0)
Will Marcouiller:我发现语法没有错误。
using (var cnx = new OleDbConnection(new AdministradorDAO().conexao))
{
var sql = @"insert into usuarios(matricula, nome, senha, nivel, maleta, email) values (@matricula, @nome, @senha, @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("@senha", 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(); }
}
}