Android Studio Java如何获取用户输入作为SQLite新建表的表名
Android中使用EditText输入作为SQLite表名的正确实现
首先明确核心规则:SQLite的?参数绑定机制只支持替换查询/写入的字面量值,完全不支持替代表名、列名这类SQL标识符,没法通过传参的方式动态设置表名。正确的做法是先对用户输入做严格合法性校验,确认输入完全符合表名规范后,再拼接进SQL语句执行,绝对不能直接拼接未校验的用户输入,否则会存在严重SQL注入风险。
实现步骤
- 获取EditText输入内容,先去除首尾空格、做空值判断
- 对输入做多层规则校验,完全符合SQLite表名命名要求后再使用
- 将合法表名拼接进建表SQL,执行
execSQL完成建表
强制校验规则
必须做以下校验,从根源避免SQL注入和语法错误:
- 非空校验:输入内容不能为空
- 字符规则:仅允许字母、数字、下划线,且必须以字母开头,长度建议控制在30位以内
- 关键字校验:不能使用SQLite保留关键字(如
table/select/drop/create等) - 可选重名校验:可提前查询系统表
sqlite_master判断该表名是否已存在,避免和已有表冲突
代码示例(Kotlin)
// 1. 获取用户输入 val tableNameInput = binding.etTableName.text.toString().trim() // 2. 逐层校验输入合法性 // 非空校验 if (tableNameInput.isEmpty()) { Toast.makeText(this, "表名不能为空", Toast.LENGTH_SHORT).show() return } // 字符格式正则校验 val validNameRegex = Regex("^[a-zA-Z][a-zA-Z0-9_]{0,29}$") if (!validNameRegex.matches(tableNameInput)) { Toast.makeText(this, "表名需以字母开头,仅支持字母、数字、下划线,长度不超过30位", Toast.LENGTH_SHORT).show() return } // SQLite保留关键字校验 val sqliteKeywords = setOf("create", "drop", "table", "select", "insert", "update", "delete", "from", "where", "index", "view", "trigger") if (tableNameInput.lowercase() in sqliteKeywords) { Toast.makeText(this, "表名不能使用SQL保留关键字", Toast.LENGTH_SHORT).show() return } // 3. 拼接SQL执行,用反引号包裹表名进一步避免语法冲突 val createTableSql = """ CREATE TABLE IF NOT EXISTS `$tableNameInput` ( _id INTEGER PRIMARY KEY AUTOINCREMENT, -- 替换为你实际需要的业务字段 content TEXT NOT NULL, create_time INTEGER NOT NULL ) """.trimIndent() runCatching { database.execSQL(createTableSql) }.onSuccess { Toast.makeText(this, "表创建成功", Toast.LENGTH_SHORT).show() }.onFailure { Toast.makeText(this, "建表失败:${it.message}", Toast.LENGTH_SHORT).show() }
常见错误写法
不要尝试用参数绑定传递表名,如下写法会直接触发SQL语法错误:
// 错误写法:?占位符不能替代表名,执行必然失败 database.execSQL("CREATE TABLE IF NOT EXISTS ? (_id INTEGER PRIMARY KEY)", arrayOf(tableNameInput))
这种写法最终生成的SQL会把表名替换成带单引号的字符串,比如CREATE TABLE IF NOT EXISTS 'test' (...),不符合SQL语法规范。
内容的提问来源于stack exchange,提问作者aslan aslanli
相关产品推荐
相关产品推荐

