1.⛲数据库的连接与断开
🎫有两种方式 1.数据源管理器中直接连接后直接引用 2.查询时指定(函数引用,下面介绍)
- 数据源管理器中直接连接过程如下:
- 点击新建
- 填写连接MySQL的基本信息(口令为密码)
- 点击连接,成功!
2.🌁Spl中用SQL实现CRUD
1.查询语句
这里用到了两种连接方法
- 在网格中调用函数连接 。( 注意:这里"test001"是数据源也就是一个数据库 && A1未close之前有效)
=connect("test001")
=A1.query("select * from test001")
>A1.close()
- 在数据源管理器中直接连接,直接query查询。(数据源管理器中连接未断开时有效)
=test001.query("select * from test001")
- 在SQL语句中,也可以使用网格中的其它数据作为参数:
[100,200,300]
=test001.query("select * from test001 where id in(?) order by id ",A10)
- 可以添加@1选项只返回第1条记录。此时,通常将返回一个序列作为结果。 如下:(以序列作为结果,把第1条记录中各列的值,作为这个序列的成员)
[100,200,300]
=test001.query@1("select * from test001 where id in(?) order by id ",A10)
2.无返回值的 SQL(insert、update、delete等SQL语句)
- Insert
>test001.execute("insert into test001 values (1001,'xiaoyi',18) ")
=test001.query("select * from test001 where name='xiaioyi'")
也可以赋值(格式都一样这里不多写了,看下面例子)
- Update于不需要对单元格赋值,在表达式开头使用">"代替"="
🎃注意这里有个坑,注意双引号的个数,很容易看错,字符串要用双引号" "括起来
>test001.execute("update test001 set name='2' where id =2")
也可以通过赋值来更新
3
4
>test001.execute("update test001 set name=? where id =?",A6,A7)
=test001.query("select * from test001 where id =?",A7)
- Delete
>test001.execute("delete from test001 where name = 'xiaoyi' ")
3.注意再执行上述的过程中一旦一个操作语句发生错误将无法执行接下来的语句。(这是其内部自动提交造成的)不符原子性。我们就可以通过设置不自动提交来避免上述情况的产生。
这里我举官方的例子 。
这里我们看到iif A5.error()==0为false 则出现了错误,为什么出现错误呢?通过=create(Fd1,Fd2,Fd3).record([A1:C4])我们可以看到出现了three(非int型的值)所以出现了赋值错误,因此走向了else->>A5.rollback(),我们可以看到后续的query也为空。
而后又执行了>A5.execute("drop table TEST")删除了表,则表的添加和赋值失败。
👀注意:
- connect函数使用了@e选项,因此在循环执行B7中的代码更新数据时,出现错误并不会中止执行。
- execute函数使用了@k选项,执行结果不会自动提交。
4.用序表或序列更新数据
从上面的例子我们可以看到,可以 用for循环函数将序表中的数据更新到序表。 在集算器中,可以直接将序列或序表中数据,用update函数更新到序表。
这里通过官方的例子来学习下 (注意:数据源名称要一致)
我们可以可看到A7之前创建表的时候是没有指定主键的,当主键未指定时,会自动到数据库中寻找主键。在A7在update函数 >A5.update(A6,TEST,ID:Fd1,FULLNAME:Fd2, STATE:Fd3;ID) 语句中指定了主键-->ID。
update函数更新数据到序表后A8的query函数查询如下:
如果数据库中已经存在了主键相同的数据,结果会如何呢?我们看看下面的官方的例子(注意:数据源名称要一致)
于A6和B6中先插入两条数据,C6查询结果如下:
而后A8中执行update函数,在A9中查到TEST表中数据如下:
可以得到主键相同的数据被更新而不同的仍然存在!
使用update函数时,还可以用一些选项来进行不同的操作:
- @u表示只更新数据,而不插入新记录;
- @i表示只插入数据,而不更新已有的数值;
- @a表示在更新前清空目标表中的所有记录;
- @1表示第一个字段为自增字段,更新时不对它赋值。
如将上例中A8中的语句修改为=A5.update@u(A7,TEST,ID:Fd1,FULLNAME:Fd2,STATE:Fd3;ID),A9中查到的结果如下:
可以得到 @u表示只更新数据,而不插入新记录。
若将上例中A8中的语句修改为=A5.update@a(A7,TEST,ID:Fd1,FULLNAME:Fd2,STATE:Fd3;ID),A9中查到的结果如下:
可以得到 @a表示在更新前清空目标表中的所有记录。
3.🌃在单元格中直接使用 SQL
除了使用db.query(sql) 函数和db.execute(sql) 函数,在集算器中还可以用 $(db)sql;来直接执行SQL。
👀注意:
- 如果(db)省略,则取之前最后一次使用的数据库连接。
- 其中的sql语句可以带参数,写在分号后面即可(db.query(sql) 函数和db.execute(sql) 函数在“,后)。
- 用这种方法时,使用sql语句时不在前方加等号,也不必将语句用引号标记,但是不再支持使用@1选项。
- 此时,不需再用execute或者query函数来区分是否返回结果集。其中select语句会返回结果集,其它语句会各自返回不同的值。如:
下面来个官方例子看下区别
其中A1中新建一个序表,A2中插入1条记录。A4中修改记录中的数据,A6中删除序表。在A3与A5中查询到的数据库更新情况如下:
可以得出结论:A1和A6(创表删表语句) 中的结果表示SQL语句未返回结果集(false) ;A2和A4(插入、更新语句) 中的结果表示更新了1条记录。
4.🏝️对 SQL 的查询结果进行过滤
在集算器中,可以利用SQL的查询结果,进行过滤、排序、组合等等操作,以提高查询效率,或者解决一些比较复杂的条件查询的问题。
举个例子
=test001.query("select * from test001 where id<10 order by id desc" )
接下来对其进行数据过滤->"name属性以s开头"
🍭SQL过滤(注意MySQL对大小写不敏感)
=test001.query("select * from test001 where id<10 and name like 's%' order by id desc" )
🍭SPL过滤(s需为大写S)
=test001.query("select * from test001 where id<10 order by id desc" )
=A1.select(left(name,1)=="S")
//这里也可以使用cont来计算个数
=A1.count(left(name,1)=="S")
//对应MySQL
=test001.query("select count(*) from test001 where id<10 and name like 's%' order by id desc" )
//其他过滤
A2[Sakurai Itsuki]
=A1.count(A2.contain(name))
=A1.count(A2.pos(name)>0)
⛲对名字首字母进行过滤分组
=test001.query("select * from test001 where id<10 order by id desc" )
=A1.group(left(name,1))
接下来对他们进行再过滤
=A2.select(~.age>200)
可以看到age为的169的Sakurai Itsuki个体被过滤了,接下来再过滤一波。
⚒️注意: ”:“相当于SQL的as,后面会讲到。
=A3.new(left(name,1):fistword, ~.age:ages, ~.id:ID)
5.🐯常见的 SQL 语句与集算器语法的对照
其实就是用SQL和SPL语句查询相同的结果
- select * from :这个比较简单,就是普通的查询
- select … from :A1 和A3结果一样
- as: 相当于 ”:“ 如下
- where: 条件查询 (注意:SQL查询同样的结果,语法复杂得多,且这里由于计算年龄时不精确,因此结果也存在一点的误差。)
- count、sum、avg、max和min 同样的例子将select 改为count(*)
🛶注意: 这里count 要求计算准确的结果,获得的查询结果和A3中的一致,但无法利用已有的结果,而语句也复杂得多。sum、avg、max和min等SQL函数的使用方法和count基本类似。
- distinct:
🎳这里巧妙运用主键来去重
- order by :查询年龄小于35岁的员工,并按照年龄降序排序,同龄员工按全名升序排序(年龄降序->
.sortd(-AGE,FULLNAME)同龄->全名new(FULLNAME,AGE)),A3与A4中的查询结果相同,如下:
- and、or、not和<>:
and <->&&
- like: name中以a结尾的员工。
- group: 根据员工所在部门分组,在集算器中,可以用group函数对记录分组,如下:
(注意:group后第一个符号是 ”;“ 第二个为 ”:“ , ”~“ 表示引用group的结果)