C语言教程:如何修改数据库中的数据 (c修改数据库中的数据)

随着信息化时代的不断发展,数据库已经成为了计算机系统中不可或缺的一部分。作为一种常见的数据存储方式,数据库不仅可以存储大规模的数据,还可以在不同的系统之间进行数据共享和数据交换。在实际应用中,一旦数据库中的数据发生了变化,往往需要使用编程语言来对其进行修改。本文将介绍如何使用C语言修改数据库中的数据。

一、连接数据库

在C语言中,要想对数据库中的数据进行修改,必须首先连接到数据库服务器。连接数据库的方法分为两种,一种是使用ODBC连接,另外一种是使用第三方的库文件连接,如MySQL提供的libmysql.dll库文件。本文将以使用ODBC连接数据库为例进行说明。

需要在代码中调用头文件#include 和#include ,同时还需要准备一些连接数据库的变量,其中包括一个SQLHENV类型的变量,一个SQLHDBC类型的变量和一个SQLHSTMT类型的变量。这三个变量分别代表了ODBC环境句柄、数据库连接句柄和语句句柄。

需要调用SQLAllocHandle函数来分配ODBC句柄。SQLAllocHandle函数包括三个参数,之一个参数为需要分配的句柄的类型,第二个参数为其父句柄,第三个参数为该句柄需要赋予的属性值。对于ODBC环境句柄和数据库连接句柄,可以不用指定其父句柄,而在语句句柄上,需要指定其父句柄为数据库连接句柄。

需要调用SQLConnect函数连接到数据库。SQLConnect函数包括五个参数,分别为数据库连接句柄、数据库用户名、数据库密码、数据库服务器名和数据库名称。以MySQL数据库为例,通过调用SQLConnect函数连接到MySQL数据库的例子代码如下所示:

“`c

SQLHENV henv;

SQLHDBC hdbc;

SQLHSTMT hstmt;

SQLRETURN retcode;

SQLCHAR* dsn = (SQLCHAR*)”Data Source=test”;

SQLCHAR* user = (SQLCHAR*)”root”;

SQLCHAR* pswd = (SQLCHAR*)”123456″;

SQLCHAR* serv = (SQLCHAR*)”localhost”;

SQLCHAR* db = (SQLCHAR*)”test”;

retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);

retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0);

retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);

retcode = SQLConnectA(hdbc, serv, SQL_NTS, user, SQL_NTS, pswd, SQL_NTS);

if (retcode != SQL_SUCCESS) {

printf(“connect to mysql fled!\n”);

return 0;

}

“`

二、修改数据库中的数据

连接到数据库后,就可以开始对数据库中的数据进行修改了。修改数据操作的核心在于SQL语句的执行。在C语言中,可以通过调用SQLExecDirect函数执行SQL语句。SQLExecDirect函数包括两个参数,分别为语句句柄和指向SQL语句的字符串指针。

对于修改数据操作,常用的SQL语句有INSERT、UPDATE和DELETE。其中,INSERT用于向数据库中添加新的数据记录,UPDATE用于更新数据库中的数据记录,DELETE用于删除数据库中的数据记录。下面分别介绍这三种SQL语句的用法。

1.修改数据

要修改数据库中的数据,首先需要使用SELECT语句查询出需要修改的数据记录。例如,要修改学号为001的学生的姓名为“小明”,可以使用如下的SQL语句:

“`sql

SELECT * FROM student WHERE sno=’001′;

“`

查询到符合条件的数据记录后,就可以使用UPDATE语句来修改该数据记录的内容。例如,将上述查询结果中的sname字段修改为“小明”,可以使用如下的SQL语句:

“`sql

UPDATE student SET sname=’小明’ WHERE sno=’001′;

“`

注意,需要将表名和字段名按照实际情况进行修改。

为了在C语言中执行上述的SQL语句,可以使用如下的代码:

“`c

char sql[1024] = { 0 };

sprintf(sql, “UPDATE student SET sname=’小明’ WHERE sno=’001′”);

retcode = SQLExecDirectA(hstmt, (SQLCHAR*)sql, SQL_NTS);

“`

上述代码中,sprintf函数用于组合SQL语句,通过拼接字符串的方式生成完整的SQL语句字符串。SQLExecDirectA函数用于执行SQL语句。

2.插入数据

要想向数据库中插入新的数据记录,可以使用INSERT语句。例如,要向student表中插入学号为“002”的学生,可以使用如下的SQL语句:

“`sql

INSERT INTO student(sno, sname) VALUES(‘002’, ‘小红’);

“`

这条SQL语句会在student表中添加一条新的数据记录,将sno字段设为“002”,将sname字段设为“小红”。

在C语言中执行上述的SQL语句,可以使用如下的代码:

“`c

char sql[1024] = { 0 };

sprintf(sql, “INSERT INTO student(sno, sname) VALUES(‘002’, ‘小红’)”);

retcode = SQLExecDirectA(hstmt, (SQLCHAR*)sql, SQL_NTS);

“`

3.删除数据

要想从数据库中删除数据记录,可以使用DELETE语句。例如,要从student表中删除学号为“002”的学生,可以使用如下的SQL语句:

“`sql

DELETE FROM student WHERE sno=’002′;

“`

这条SQL语句会将student表中符合条件的数据记录全部删除。

在C语言中执行上述的SQL语句,可以使用如下的代码:

“`c

char sql[1024] = { 0 };

sprintf(sql, “DELETE FROM student WHERE sno=’002′”);

retcode = SQLExecDirectA(hstmt, (SQLCHAR*)sql, SQL_NTS);

“`

三、关闭数据库连接

在C语言中执行完数据库操作后,需要调用SQLDisconnect函数断开与数据库服务器的连接,并释放ODBC的句柄空间。例如:

“`c

SQLDisconnect(hdbc);

SQLFreeHandle(SQL_HANDLE_DBC, hdbc);

SQLFreeHandle(SQL_HANDLE_ENV, henv);

“`

SQLDisconnect函数用于断开与数据库服务器的连接,SQLFreeHandle函数用于释放分配的句柄空间。

四、完整代码

下面是使用C语言修改数据库中数据的完整代码:

“`c

#include

#include

#include

int mn(int argc, char* argv[])

{

SQLHENV henv;

SQLHDBC hdbc;

SQLHSTMT hstmt;

SQLRETURN retcode;

SQLCHAR* dsn = (SQLCHAR*)”Data Source=test”;

SQLCHAR* user = (SQLCHAR*)”root”;

SQLCHAR* pswd = (SQLCHAR*)”123456″;

SQLCHAR* serv = (SQLCHAR*)”localhost”;

SQLCHAR* db = (SQLCHAR*)”test”;

char sql[1024] = { 0 };

retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);

retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0);

retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);

retcode = SQLConnectA(hdbc, serv, SQL_NTS, user, SQL_NTS, pswd, SQL_NTS);

if (retcode != SQL_SUCCESS) {

printf(“connect to mysql fled!\n”);

return 0;

}

retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);

if (retcode != SQL_SUCCESS) {

printf(“SQLAllocHandle fled!\n”);

return 0;

}

sprintf(sql, “SELECT * FROM student WHERE sno=’001′”);

retcode = SQLExecDirectA(hstmt, (SQLCHAR*)sql, SQL_NTS);

while (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {

SQLCHAR sno[32] = { 0 };

SQLCHAR sname[64] = { 0 };

SQLINTEGER age = 0;

SQLLEN len1 = 0, len2 = 0, len3 = 0;

retcode = SQLBindCol(hstmt, 1, SQL_C_CHAR, sno, sizeof(sno), &len1);

retcode = SQLBindCol(hstmt, 2, SQL_C_CHAR, sname, sizeof(sname), &len2);

retcode = SQLBindCol(hstmt, 3, SQL_C_SLONG, &age, 0, &len3);

retcode = SQLFetch(hstmt);

if (retcode == SQL_NO_DATA) {

break;

}

printf(“sno:%s sname:%s age:%d\n”, sno, sname, age);

}

sprintf(sql, “UPDATE student SET sname=’小明’ WHERE sno=’001′”);

retcode = SQLExecDirectA(hstmt, (SQLCHAR*)sql, SQL_NTS);

sprintf(sql, “SELECT * FROM student WHERE sno=’001′”);

retcode = SQLExecDirectA(hstmt, (SQLCHAR*)sql, SQL_NTS);

while (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {

SQLCHAR sno[32] = { 0 };

SQLCHAR sname[64] = { 0 };

SQLINTEGER age = 0;

SQLLEN len1 = 0, len2 = 0, len3 = 0;

retcode = SQLBindCol(hstmt, 1, SQL_C_CHAR, sno, sizeof(sno), &len1);

retcode = SQLBindCol(hstmt, 2, SQL_C_CHAR, sname, sizeof(sname), &len2);

retcode = SQLBindCol(hstmt, 3, SQL_C_SLONG, &age, 0, &len3);

retcode = SQLFetch(hstmt);

if (retcode == SQL_NO_DATA) {

break;

}

printf(“sno:%s sname:%s age:%d\n”, sno, sname, age);

}

sprintf(sql, “INSERT INTO student(sno, sname) VALUES(‘002’, ‘小红’)”);

retcode = SQLExecDirectA(hstmt, (SQLCHAR*)sql, SQL_NTS);

sprintf(sql, “SELECT * FROM student WHERE sno=’002′”);

retcode = SQLExecDirectA(hstmt, (SQLCHAR*)sql, SQL_NTS);

while (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {

SQLCHAR sno[32] = { 0 };

SQLCHAR sname[64] = { 0 };

SQLINTEGER age = 0;

SQLLEN len1 = 0, len2 = 0, len3 = 0;

retcode = SQLBindCol(hstmt, 1, SQL_C_CHAR, sno, sizeof(sno), &len1);

retcode = SQLBindCol(hstmt, 2, SQL_C_CHAR, sname, sizeof(sname), &len2);

retcode = SQLBindCol(hstmt, 3, SQL_C_SLONG, &age, 0, &len3);

retcode = SQLFetch(hstmt);

if (retcode == SQL_NO_DATA) {

break;

}

printf(“sno:%s sname:%s age:%d\n”, sno, sname, age);

}

sprintf(sql, “DELETE FROM student WHERE sno=’002′”);

retcode = SQLExecDirectA(hstmt, (SQLCHAR*)sql, SQL_NTS);

sprintf(sql, “SELECT * FROM student WHERE sno=’002′”);

retcode = SQLExecDirectA(hstmt, (SQLCHAR*)sql, SQL_NTS);

while (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO) {

SQLCHAR sno[32] = { 0 };

SQLCHAR sname[64] = { 0 };

SQLINTEGER age = 0;

SQLLEN len1 = 0, len2 = 0, len3 = 0;

retcode = SQLBindCol(hstmt, 1, SQL_C_CHAR, sno, sizeof(sno), &len1);

retcode = SQLBindCol(hstmt, 2, SQL_C_CHAR, sname, sizeof(sname), &len2);

retcode = SQLBindCol(hstmt, 3, SQL_C_SLONG, &age, 0, &len3);

retcode = SQLFetch(hstmt);

if (retcode == SQL_NO_DATA) {

break;

}

printf(“sno:%s sname:%s age:%d\n”, sno, sname, age);

}

SQLDisconnect(hdbc);

SQLFreeHandle(SQL_HANDLE_STMT, hstmt);

SQLFreeHandle(SQL_HANDLE_DBC, hdbc);

SQLFreeHandle(SQL_HANDLE_ENV, henv);

return 0;

}

“`

相关问题拓展阅读:

c/s系统,如何防止用户直接连到数据库修改数据

1. 事实上,交易不帮你在这里多…除非你想有运行在多个HTTP请求(你很可能不希望)的交易。 有什么用在这些情况下是“乐观锁定”。 Django的ORM不支持,据我所知。但一直以来关于添加此功能。 那么,你是你自己的。基本上,你应该做的就是添加一个“版本”字段,你的模型,并把它传递给一个隐藏字段。正常周期的更新是: 读取数据并显示给 用户可以修改数据 用户发布的数据 该应用程序将其保存回数据库。 乐观锁,当你保存数据,你检查,如果你得到了从后面的版本是作为一个在数据库中,然后更新数据库和版本。如果它们不是,那有一直以来被加载的数据的变化。 你可以做到这一点与像一个单一的SQL调用:UPDATE … WHERE version = ‘version_from_user’;

这个调用将更新数据库只有在版本仍然是

2. 我就是这样做的Django的乐观锁:updated = Entry.objects.filter(Q(id=e.id) && Q(version=e.version))\

.update(updated_field=new_value, version=e.version+1)

if not updated:

raise ConcurrentModificationException()

上面列出的代码可以在自定义管理。 我提出以下假设: 筛选()。update()方法会导致在一个单一的数据库查询过滤器是懒惰 数据库查询是原子 这些假设都足以确保没有其他人之前已经更新了条目。如果有多个行被更新这样你的交易。 警告Django的文件: 请注意,update()方法是 直接转换为SQL 这是一个批量操作 直接更新。它不运行任何 保存(您的模型)的方法,或发出 该pre_save或post_save信号

3. 这个问题是有点老了,我的回答有点晚,但经过我的理解使用这个已被固定在Django 1.4:select_for_update(nowait=True)

看到文档 返回一个QuerySet,将锁定行,直到事务结束,产生一个SELECT …有关支持的数据库UPDATE的SQL。 通常情况下,如果另一个事务已获得所选择的行上的锁,则查询将阻塞,直到锁被释放。如果这不是你想要的行为,请致电select_for_update(NOWAIT=TRUE)。这将使调用非阻塞的。如果已经获取了冲突的锁被另一个事务时的QuerySet进行评估,DatabaseError的将得到提升。 当然,这只会工作,如果后端支持的“选择更新”功能,这对于例如SQLite不。不幸的是:nowait=True不支持MySql的,有你有nowait=False,这只会阻塞,直到锁被释放。

4. 对于未来的参考,退房离开的时候(在浏览器中,例如崩溃)的页面,并锁定它锁定的方式,不留下永恒的锁,通过javascript的解锁的混合物。下

5. 你应该Django的交易中间件,至少,甚至不管这个问题。 至于你实际有编辑数据的问题…是的,使用锁。或: 检查什么版本正在更新对(这样做牢固,誉裂不能简单地破解系统说,他们正在更新的最新副本!),且仅当该版本是最新的更新。否则,返回一个新页面与原来的版本,他们编辑,他们提交的版本,和别人写的新版本(S)。问他们变成一体,完全取决于最新的版本。你可以尝试类似的diff +补丁工具集,但你需要有方法工作失败的案例,无论如何,所以开始了。此外,您将需要保存的版本历史记录,并允许管理员恢复的变化,在无意的情况下或向上,但你应该有反正。 有很可能是Django应用程序/库,做这个最适合你。

6. 为了安全起见,数据库需要支持事务。 如果字段是“自由形式”如文字等等,你需要允许可以编辑的字段(你不能有所有权的数据),你可以存储在变量中的原始数据。 当committs,检查输入数据从原迹虚兆始数据更改(如果不是,你不姿租需要通过重写旧数据打扰DB) 如果原来在数据库中的当前数据是可以保存,如果它改变了你可以示区别,并问该怎么办。 如果字段是一个数字如账户余额,在商店等项目的数量,你可以自动处理它,如果你计算出原始值(存储开始时填写表单)和新的价值,你就可以开始一个事务读取当前值之间的差额新增的差别,然后结束交易。如果你不能有负值,则应该中止交易,如果结果为负,并告诉 我不知道Django的,所以我不能给你德cod3s .. 😉

7. 另一个需要注意的是这个词“原子”.a个原子,你的数据库的更改要么发生或无法快速搜索说明这个问题问Django中的原子操作。

8. 上面的想法updated = Entry.objects.filter(Q(id=e.id) && Q(version=e.version))\

.update(updated_field=new_value, version=e.version+1)

if not updated:

raise ConcurrentModificationException()

看起来不错,应该能正常运行,即使没有序列化的交易。 问题是如何将deafult。保存()的行为,以不必须做人工管道来调用。update()方法。 我看着自定义管理想法。 我的计划是覆盖被称为Model.save_base()来执行更新的经理。 这是在Django 1.3当前代码def _update(self, values, **kwargs):

return self.get_query_set()._update(values, **kwargs)

什么需要恕我直言做的是这样的:def _update(self, values, **kwargs):

#TODO Get version field value

v = self.get_version_field_value(values)

return self.get_query_set().filter(Q(version=v))._update(values, **kwargs)

类似的事情需要发生的删除。但是删除是有点难度的Django是相当巫术在这方面通过django.db.models.deletion.Collector。 这是奇怪的,像Django的modren工具缺乏对Optimictic Concurency控制指导。 当我解开这个谜,我会更新这个帖子。希望解决方案将是不涉及万吨编码,怪异的意见,跳绳重要部分的Django等的一个很好的Python的方式

9. 从这里开始: 我假设将举行一个隐藏字段中你试图挽救细节的表格。def save(self):

if(self.id):

foo = Foo.objects.get(pk=self.id)

if(foo.timestamp > self.timestamp):

raise Exception, “trying to save outdated Foo”

c修改数据库中的数据的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于c修改数据库中的数据,C语言教程:如何修改数据库中的数据,c/s系统,如何防止用户直接连到数据库修改数据的信息别忘了在本站进行查找喔。


数据运维技术 » C语言教程:如何修改数据库中的数据 (c修改数据库中的数据)