基于AScript的SQL脚本语言发布啦!
一、介绍支持SqlServer/MySql基础语法和数据类型支持SELECT查询语法FROM/WHERE/LEFT JOIN/RIGHT JOIN/INNER JOIN/GROUP BY/ORDER BY/LIMIT支持INSERT插入语法支持UPDATE修改语法支持DELETE删除语法支持创建存储过程Sqlserver/MySql语法都支持支持创建表支持定义变量字段名、关键字不区分大小写支持调用外部方法和变量已内置常用数据类型tinyint/smallint/int/bigint/decimal/float/real/double/bit/char/nchar/varchar/nvarchar/text/datetime不支持存储过程暂不支持OUT参数SELECT查询不支持*号SELECT查询不支持聚合函数二、安装1 install-package AScript 2 install-package AScript.Lang.Sql三、使用说明1、注册语言1 Script.Langs.Set(sql, SqlLang.Instance); 2 // 可全局设置为默认语言 3 // Script.Langs.Set(sql, SqlLang.Instance, setDefault: true);2、单表查询select多个字段生成匿名类型1 var s select Name, Age from list where age10; 2 var list new[] { new Person(tom, 15), new Person(jim, 10), new Person(san, 20), new Person(qin, 10) }; 3 var script new Script(); 4 script.Context.Langs new[] { sql }; 5 script.Context.SetVar(list, list); 6 var result script.EvalIEnumerabledynamic(s).ToList(); 7 Assert.AreEqual(2, result.Count); 8 Assert.AreEqual(jim, result[0].Name); 9 Assert.AreEqual(10, result[0].Age); 10 Assert.AreEqual(qin, result[1].Name); 11 Assert.AreEqual(10, result[1].Age);select一个字段1 var s select Name from list where age10; 2 var list new[] { new Person(tom, 15), new Person(jim, 10), new Person(san, 20), new Person(qin, 10) }; 3 var script new Script(); 4 script.Context.Langs new[] { sql }; 5 script.Context.SetVar(list, list); 6 var result script.EvalIEnumerablestring(s).ToList(); 7 Assert.AreEqual(2, result.Count); 8 Assert.AreEqual(jim, result[0]); 9 Assert.AreEqual(qin, result[1]);3、单独from语句1 var s from list where age10; 2 var list new[] { new Person(tom, 15), new Person(jim, 10), new Person(san, 20), new Person(qin, 10) }; 3 var script new Script(); 4 script.Context.Langs new[] { sql }; 5 script.Context.SetVar(list, list); 6 var result script.EvalIEnumerablePerson(s).ToList(); 7 Assert.AreEqual(2, result.Count); 8 Assert.AreEqual(jim, result[0].Name); 9 Assert.AreEqual(10, result[0].Age); 10 Assert.AreEqual(qin, result[1].Name); 11 Assert.AreEqual(10, result[1].Age);4、多表查询1 string s 2 var q1 new[] { new Person(tom, 20), new Person(jim, 25), new Person(san, 18), new Person(kit, 30) }.AsQueryable(); 3 var q2 new[] { new AddressInfo(jim, a), new AddressInfo(cc, b), new AddressInfo(tom, c), new AddressInfo(ee, d) }.AsQueryable(); 4 lang sql 5 select a.Name, a.Age, b?.Address, case a.Age when 25 then 1 else 2 end as Level 6 from q1 as a 7 left join q2 as b on a.Name b.UserName 8 where a.age 22 9 order by a.age desc 10 ; 11 var script new Script(); 12 script.Context.AddTypePerson(); 13 script.Context.AddTypeAddressInfo(); 14 var list script.EvalIEnumerabledynamic(s).ToList(); 15 Assert.AreEqual(2, list.Count); 16 Assert.AreEqual(kit, list[0].Name); 17 Assert.AreEqual(30, list[0].Age); 18 Assert.AreEqual(2, list[0].Level); 19 Assert.IsNull(list[0].Address); 20 Assert.AreEqual(jim, list[1].Name); 21 Assert.AreEqual(25, list[1].Age); 22 Assert.AreEqual(a, list[1].Address); 23 Assert.AreEqual(1, list[1].Level);5、INSERT执行insert语句返回插入记录的数量。1 var s insert into list (Name, Age) values (tom, 20), (jim, 25); 2 var list new ListPerson(); 3 var script new Script(); 4 script.Context.Langs new[] { sql }; 5 script.Context.SetVar(list, list); 6 Assert.AreEqual(2, script.Eval(s)); 7 Assert.AreEqual(2, list.Count); 8 Assert.AreEqual(tom, list[0].Name); 9 Assert.AreEqual(20, list[0].Age); 10 Assert.AreEqual(jim, list[1].Name); 11 Assert.AreEqual(25, list[1].Age);6、UPDATE执行update语句返回修改记录的数量。1 var s update list set Age28 where Age25; 2 var list new ListPerson 3 { 4 new Person(jim, 18), 5 new Person(tom, 20), 6 new Person(lily, 30) 7 }; 8 var script new Script(); 9 script.Context.Langs new[] { sql }; 10 script.Context.SetVar(list, list); 11 var count (int)script.Eval(s); 12 Assert.AreEqual(2, count); 13 Assert.AreEqual(28, list[0].Age); 14 Assert.AreEqual(28, list[1].Age); 15 Assert.AreEqual(30, list[2].Age);7、DELETE执行delete语句返回删除记录的数量。1 var s delete from list where Age25; 2 var list new ListPerson 3 { 4 new Person(jim, 18), 5 new Person(tom, 20), 6 new Person(lily, 30) 7 }; 8 var script new Script(); 9 script.Context.Langs new[] { sql }; 10 script.Context.SetVar(list, list); 11 var count (int)script.Eval(s); 12 Assert.AreEqual(2, count); 13 Assert.AreEqual(1, list.Count); 14 Assert.AreEqual(lily, list[0].Name);8、SqlServer存储过程如果有多条语句则使用begin..end只有一条语句可以不写begin..end。1 var s 2 CREATE PROCEDURE AddPerson 3 name VARCHAR, 4 age INT 5 AS 6 BEGIN 7 INSERT INTO list (name, age) VALUES(name, age) 8 END 9 EXEC AddPerson tom, 20 10 ; 11 var list new ListPerson(); 12 var script new Script(); 13 script.Context.Langs new[] { sql }; 14 script.Context.SetVar(list, list); 15 Assert.AreEqual(1, script.Eval(s)); 16 Assert.AreEqual(1, list.Count); 17 Assert.AreEqual(tom, list[0].Name); 18 Assert.AreEqual(20, list[0].Age);9、MySql存储过程如果有多条语句则使用begin..end只有一条语句可以不写begin..end。1 var s 2 CREATE PROCEDURE AddPerson(name VARCHAR, age INT) 3 BEGIN 4 DECLARE name2 VARCHAR 5 DECLARE age2 INT 6 SET name2 name 2 7 SET age2 age 10 8 INSERT INTO list (name, age) VALUES(name, age),(name2, age2) 9 END 10 CALL AddPerson(tom, 20); 11 var list new ListPerson(); 12 var script new Script(); 13 script.Context.Langs new[] { sql }; 14 script.Context.SetVar(list, list); 15 Assert.AreEqual(2, script.Eval(s)); 16 Assert.AreEqual(2, list.Count); 17 Assert.AreEqual(tom, list[0].Name); 18 Assert.AreEqual(20, list[0].Age); 19 Assert.AreEqual(tom2, list[1].Name); 20 Assert.AreEqual(30, list[1].Age);10、创建函数1 var s 2 CREATE FUNCTION Calc(a INT, b INT) 3 RETURNS INT 4 BEGIN 5 DECLARE sum INT 6 SET sum a * b a b 7 RETURN sum 8 END 9 SELECT Calc(2, 3) 10 ; 11 var script new Script(); 12 script.Context.Langs new[] { sql }; 13 var result script.Eval(s); 14 Assert.AreEqual(11, result);11、创建表表字段支持主键PRIMARY KEY)、自增IDENTITY(1,1)或者AUTO_INCREMENT、默认值DEFAULT、可空NULL、非空NOT NULL、最大长度定义。简单示例1 var s 2 CREATE TABLE person (name varchar, age int) 3 INSERT INTO person (name, age) VALUES (tom, 20),(jim, 25),(san, 18) 4 UPDATE person SET age 30 WHERE name tom 5 DELETE FROM person WHERE Name jim 6 SELECT Name,age FROM person WHERE age 22 7 ; 8 var script new Script(); 9 script.Context.Langs new[] { sql }; 10 var list script.EvalIEnumerabledynamic(s).ToList(); 11 Assert.AreEqual(1, list.Count); 12 Assert.AreEqual(tom, list[0].Name); 13 Assert.AreEqual(30, list[0].age);复杂示例1 var s 2 CREATE TABLE student_scores ( 3 id INT PRIMARY KEY AUTO_INCREMENT, 4 name VARCHAR(50), 5 subject VARCHAR(20), 6 score INT NOT NULL DEFAULT 0, 7 class_level VARCHAR(10) 8 ); 9 10 INSERT INTO student_scores (name,subject,score,class_level) VALUES 11 (张三,数学,85,A), 12 (李四,数学,92,B), 13 (王五,数学,78,A), 14 (赵六,数学,45,C); 15 16 SELECT 17 id, 18 name, 19 score, 20 CASE 21 WHEN score 90 THEN 优秀 22 WHEN score 80 THEN 良好 23 WHEN score 60 THEN 及格 24 ELSE 不及格 25 END AS basic_grade, 26 CASE 27 WHEN score 90 THEN 28 CASE WHEN class_levelA THEN 顶尖 ELSE 优秀 END 29 WHEN score 80 THEN 潜力 30 ELSE 需加强 31 END AS advanced_grade 32 FROM student_scores; 33 ; 34 var script new Script(); 35 script.Context.Langs new[] { sql }; 36 var list script.EvalIEnumerabledynamic(s).ToList(); 37 Assert.AreEqual(4, list.Count); 38 Assert.AreEqual(1, list[0].id); 39 Assert.AreEqual(张三, list[0].name); 40 Assert.AreEqual(85, list[0].score); 41 Assert.AreEqual(良好, list[0].basic_grade); 42 Assert.AreEqual(潜力, list[0].advanced_grade); 43 Assert.AreEqual(2, list[1].id); 44 Assert.AreEqual(李四, list[1].name); 45 Assert.AreEqual(92, list[1].score); 46 Assert.AreEqual(优秀, list[1].basic_grade); 47 Assert.AreEqual(优秀, list[1].advanced_grade); 48 Assert.AreEqual(3, list[2].id); 49 Assert.AreEqual(王五, list[2].name); 50 Assert.AreEqual(78, list[2].score); 51 Assert.AreEqual(及格, list[2].basic_grade); 52 Assert.AreEqual(需加强, list[2].advanced_grade); 53 Assert.AreEqual(4, list[3].id); 54 Assert.AreEqual(赵六, list[3].name); 55 Assert.AreEqual(45, list[3].score); 56 Assert.AreEqual(不及格, list[3].basic_grade); 57 Assert.AreEqual(需加强, list[3].advanced_grade);12、SQL to LINQ项目中我们经常使用LINQ to SQL如果反过来SQL to LINQ是啥样呢1 using (var context new TestSqliteContext()) 2 { 3 var s 4 select 5 p.Id, 6 p.Name, 7 p.Age, 8 a.Address as MyAddress, 9 case p.Age when 20 then 1 when 22 then 2 else 3 end as Level 10 from context.Persons as p 11 left join context.AddressInfos as a on p.Id a.UserId 12 ; 13 var script new Script(); 14 script.Context.Langs new[] { sql }; 15 script.Context.SetVar(context, context); 16 var list script.EvalIEnumerabledynamic(s).ToList(); 17 Console.WriteLine(JsonConvert.SerializeObject(list, Formatting.Indented)); 18 }我们通过SQL脚本来操作DbContext实现SQL to LINQ再由LINQ转SQLEF Core/FreeSql/SqlSugar等ORM执行数据库查询操作。生成的SQL语句如下1 SELECT p.Id, p.Name, p.Age, a.Address AS MyAddress, CASE 2 WHEN p.Age 20 THEN 1 3 WHEN p.Age 22 THEN 2 4 ELSE 3 5 END AS Level 6 FROM Persons AS p 7 LEFT JOIN AddressInfos AS a ON p.Id a.UserId 8 ORDER BY p.Age DESC当然也可以使用SQL脚本对DbContext进行新增、修改、删除操作同上面的INSERT/UPDATE/DELETE示例。四、应用场景1前端动态查询条件和排序方式将前端传过来的条件和排序拼接为SQL字符串然后生成Lambda表达式如下1 // 前端传name、op(,,等比较符)、age 2 using (var context new TestSqliteContext()) 3 { 4 // 拼接条件字符串 5 var conditionString p.name like %name% and p.age op age; 6 var script new Script(); 7 script.Context.Langs new[] { sql }; 8 // 编译条件 9 ExpressionFuncPerson, bool condition script.LambdaPerson, bool(conditionString, p); 10 // 条件过滤 11 var result context.Persons.Where(condition).ToList(); 12 }2数据层只提供了IQuerableT可是应用层我手痒想写SQL怎么办那就用SQL to LINQ吧结束语SQL动态脚本也内置了一些函数比如获取当前时间NOW()或者GETDATE()字符串拼接CONCAT计算长度LEN(字符串或列表)或者LENGTH(字符串或列表)数学函数ABS/POW/ROUND/FLOOR/SIN/COS等

相关新闻

SpringBoot自动装配和starter

SpringBoot自动装配和starter

自动装配SpringBootApplication 注解中包含了EnableAutoConfiguration注解,这个注解底层又是import 注解,导入自动配置类导入选择器(AutoConfigurationImportSelecor ),这个选择器会去读取约定配置文件,从文…

2026/6/29 19:16:02阅读更多 →
统计学、数据科学、大数据管理,哪个更适合做数据?2026大学生选方向不迷路

统计学、数据科学、大数据管理,哪个更适合做数据?2026大学生选方向不迷路

很多同学想做数据,却卡在专业选择上:统计学偏理论,数据科学偏技术,大数据管理偏业务与治理。到了 2026 年,企业要的早已不是“会做表”的人,而是能把数据变成决策、产品和增长的人。也正因为这样&#xff0…

2026/6/29 19:16:02阅读更多 →
低功耗单片机MCU芯片主流型号盘点

低功耗单片机MCU芯片主流型号盘点

一、低功耗单片机MCU基础概念解析 低功耗单片机本质是集成度极高的微型控制芯片,行业内也常被称作MCU(微控制单元)。不同于普通微处理器,低功耗单片机通过超大规模集成电路技术,将CPU、运行内存RAM、存储ROM、外设接口…

2026/6/29 19:16:02阅读更多 →
libuvc实战:跨平台USB摄像头控制与多设备区分

libuvc实战:跨平台USB摄像头控制与多设备区分

1. 为什么需要libuvc? 当你用Linux系统连接多个相同型号的USB摄像头时,会发现一个头疼的问题:通过lsusb命令看到的设备信息完全一样。我去年做智能门禁项目时就遇到过这种情况——两个罗技C920摄像头插在工控机上,系统根本分不清谁…

2026/6/29 20:41:45阅读更多 →
面试官坏笑:“你用 Claude Code 写代码,不怕它把项目搞炸?”,我:“怕,所以 CLAUDE.md、权限和验证,一个都不能少。”

面试官坏笑:“你用 Claude Code 写代码,不怕它把项目搞炸?”,我:“怕,所以 CLAUDE.md、权限和验证,一个都不能少。”

不知道大家和我是不是有同样的感觉,刚开始用Claude Code的时候真挺别扭,甚至有点抵触:已经习惯了 Cursor、IDEA 里的侧边栏、文件树、diff 面板,再回到终端里跟 AI 协作,真心不顺手。 后来用多了,反而觉得…

2026/6/29 20:41:45阅读更多 →
5年,一个程序员是如何把私有化在线客服系统做到第一名的

5年,一个程序员是如何把私有化在线客服系统做到第一名的

一转眼 5 年过去了。今天对我来说同样是具有里程碑意义的日子,一个大客户经过长达近 3 个月的评估,测试,终于签单了。过程十分辛苦,甚至一度让我有点想放弃,包括不限于: 1)和客户的技术团队在腾…

2026/6/29 20:41:45阅读更多 →
Spring Boot 虚拟线程实战:ThreadLocal 串数据、连接池打爆、synchronized 钉住线程,三个坑及解决方案

Spring Boot 虚拟线程实战:ThreadLocal 串数据、连接池打爆、synchronized 钉住线程,三个坑及解决方案

Spring Boot 虚拟线程实战:ThreadLocal 串数据、连接池打爆、synchronized 钉住线程,三个坑及解决方案 目录 一、虚拟线程是什么二、Spring Boot 如何开启虚拟线程三、坑一:ThreadLocal 数据串了四、坑二:数据库连接池被打爆五、…

2026/6/29 20:41:45阅读更多 →
如何用Revelation光影包打造电影级Minecraft体验:完整安装与配置指南

如何用Revelation光影包打造电影级Minecraft体验:完整安装与配置指南

如何用Revelation光影包打造电影级Minecraft体验:完整安装与配置指南 【免费下载链接】Revelation An explorative shaderpack for Minecraft: Java Edition 项目地址: https://gitcode.com/gh_mirrors/re/Revelation 你是否厌倦了Minecraft单调的方块世界&a…

2026/6/29 20:41:45阅读更多 →
基于Feign+Resilience4j的微服务熔断防雪崩优化方案

基于Feign+Resilience4j的微服务熔断防雪崩优化方案

一、架构背景 1.1 调用链路 整体微服务调用层级: 网关 → 应用层服务 → 聚合层服务 → 原子层服务 → 外部第三方接口 1.2 现存隐患 原子层服务依赖外部第三方接口,第三方网络不稳定、频繁长时间超时; 原子服务Web容器线程池固定为200个Servlet工作线程; 大量请求阻塞在…

2026/6/29 20:36:44阅读更多 →
AI Coding 六个月真实ROI账本:产品经理的血泪教训,研发的冷静忠告

AI Coding 六个月真实ROI账本:产品经理的血泪教训,研发的冷静忠告

6个月前的2025年12月,Boris Cherny 公开宣布自己卸载了 IDE。一时间,Vibe Coding 成了全行业最热的话题。6个月后,当我们回过头来拉一份真实账本,发现事情远没有"一句话生成一个App"那么浪漫。本文从产品经理和研发两个…

2026/6/29 3:27:55阅读更多 →
审计来了,数据权限全开——审计走了,怎么确保权限全部关掉?

审计来了,数据权限全开——审计走了,怎么确保权限全部关掉?

引言:审计结束三个月了,审计员的权限还没关某城商行每年按照监管要求开展至少一次数据安全审计。审计期间,内审部门需要抽样检查各类业务数据——交易流水、客户信息、员工操作日志、权限配置记录。这些数据分布在不同系统中,审计…

2026/6/29 2:19:08阅读更多 →
如何在3秒内从普通图片生成专业级法线贴图:DeepBump的终极指南

如何在3秒内从普通图片生成专业级法线贴图:DeepBump的终极指南

如何在3秒内从普通图片生成专业级法线贴图:DeepBump的终极指南 【免费下载链接】DeepBump Normal & height maps generation from single pictures 项目地址: https://gitcode.com/gh_mirrors/de/DeepBump 还在为3D建模中的纹理制作而烦恼吗?…

2026/6/29 0:01:47阅读更多 →
OCAuxiliaryTools:终极OpenCore配置工具,让黑苹果安装从未如此简单!

OCAuxiliaryTools:终极OpenCore配置工具,让黑苹果安装从未如此简单!

OCAuxiliaryTools:终极OpenCore配置工具,让黑苹果安装从未如此简单! 【免费下载链接】OCAuxiliaryTools Cross-platform GUI management tools for OpenCore(OCAT) 项目地址: https://gitcode.com/gh_mirrors/oc/OCA…

2026/6/29 0:01:47阅读更多 →
终极Windows 11精简指南:使用tiny11builder快速创建纯净系统镜像

终极Windows 11精简指南:使用tiny11builder快速创建纯净系统镜像

终极Windows 11精简指南:使用tiny11builder快速创建纯净系统镜像 【免费下载链接】tiny11builder Scripts to build a trimmed-down Windows 11 image. 项目地址: https://gitcode.com/GitHub_Trending/ti/tiny11builder 你是否厌倦了Windows 11系统自带的20…

2026/6/29 0:01:47阅读更多 →