问题引入:昨天在用
sqlx
进行crud的时候,发现一个bug,导致rust编译器死活通过不了,百思不得其解,翻阅古今中外资料,仍然无法解决
截取一下出错的代码片段
刚开始还以为是语法错误,看了好久,很久都没法解决,最后一遍一遍对比没问题的代码
然后灵光一现,不会是因为teacher
表还没有创建才报错吧,报错提示如下:error returned from database: relation "teacher" does not exist
开始看到的时候就没想过rust能知道我的表不存在,这怎么可能!!!!我的表存不存在我自己都不知道,怎么可能让rust知道了呢????
没想到创建表后,编译居然通过了!!!
大离谱事件发生了呀,我这可是
硬编码
,直接把sql
写在代码里面的,这可是字符串呀!?sqlx
居然能分析出我的表不存在,从而编译失败,虽然离谱,但是真相就是这样
让我们看看gpt
选手的解释
看看gpt的解释
sqlx
在编译时进行了静态分析,并通过查询中使用的表名来检查表的存在与否。当您执行sqlx::query!
宏时,它会尝试将查询字符串解析为有效的 SQL 查询,并在编译时验证查询的语法和语义。这包括检查查询中引用的表是否存在于数据库中。
在您的代码中,当您将查询字符串设置为从course
表中选择数据时,sqlx
静态分析过程会检查数据库中是否存在名为course
的表。如果表存在,查询将被认为是有效的,并且代码不会报错。如果表不存在,则静态分析将检测到这个问题,并在编译时报错。
这是sqlx
静态分析的一个优点,它可以在编译时捕获一些潜在的问题,并提供更好的代码安全性和可靠性。通过在编译时检查表的存在与否,sqlx
可以避免在运行时出现相关的错误。
需要注意的是,sqlx
的静态分析只能检查查询中引用的表是否存在,而不能检查查询的语义是否符合预期。因此,在执行查询之前,仍然需要在运行时处理数据库返回的错误,并确保查询的结果符合预期。