请上传宽度大于 1200px,高度大于 164px 的封面图片
    调整图片尺寸与位置
    滚轮可以放大缩小图片尺寸,按住图片拖动可调整位置,多余的会自动被裁剪掉
取消
axing(uid:73248)
职业资格认证:FCP-报表开发工程师 | FCA-业务分析理论 | FCA-FineBI
问答版块BUG反馈
1. 回答问题的输入框上面插入代码功能失效 144411 以前可以对代码格式化,现在没有效果,甚至会出现格式混乱的情况 如下是以前的效果 144412 2. 问题评论里面输入引号,会自动加上斜杠,影响可读性,准确性 144413 编辑于 2021-6-11 14:45
数据刷新后最佳变少了
23日早晨数据刷新后最佳变少,已与@饭团君 沟通 刷新前 133262 刷新后133263 编辑于 2020-3-25 11:46
【数据追梦人】帆软如江湖,从无名小卒到武林高手
初入江湖,门派之争 有人的地方,就有江湖,有江湖就有门派。江湖里门派众多,比较出名的有少林、武当、峨眉、华山等,而我选择了…… 2016年3月,我离开了校园,来到了深圳这个寸土寸金的地方,开始了人生的第一个实习工作。那时候所在项目组的工作其实已接近了尾声,没有什么事情可做。每天过来上班就是喝喝开水,看看文档,然后听听技术总监吹嘘他当年的丰功伟绩,就这样维持了三个月。我觉得这样的工作与我预想的完全不一样,没有拼搏没有干劲。于是在毕业之后,果断拒绝了加薪留任,毅然地选择了辞职。 然而理想很丰满,现实很骨感,离职之后的路并不好找。因为性格比较内向,多次面试碰壁。从7月到8月,我花光了身上的所有积蓄,心里也慢慢的产生了后悔的想法,当初要是没有离职多好啊。然而世上没有后悔药,生活还要往前走。终于,在几经辗转之后,我被东鹏特饮录用了。 这时我的工作职责是负责泛微OA系统的集成开发与维护。因为大学里学过java,一开始的工作规划也是java开发方向,所以这份工作也是蛮符合心意的。但是没想到还没有开始,这份工作就已经结束了。当时公司刚上finereport不久,有两名帆软员工在现场实施项目,合同期即将结束,而我们公司这一块还没安排人员负责,于是在一次部门会议上,我就被安排负责帆软报表项目开发,那是我第一次听到finereport这个名词。就这样机缘巧合之下,拉开了我与帆软之间的故事序幕。 130204 江湖历练,方兴未艾 欲练此功,必先……江湖里每个大佬的练成,都有一个挣扎的过程…… 刚开始接触FineReport的时候,给我的感觉就是“这不就是一个excel吗”。 FineReport的入门真的是太简单了,对于一个计算机专业的人来说,几乎是一拿来就可以上手。我花了一天的时间,看了基础视频和帮助文档初级教程,然后就开始做任务。初期的任务是关于EHR的一些报表,周报、月报、离职率、留存率等,这些工作都很简单,我也顺利的完成了。 这个时候我的心里还是很犹豫,能不能在这条路上走下去。在我的内心深处,还是希望有一天能够重回java开发的道路上来。很多个下班后的晚上,我依然在电脑里敲打着java代码,琢磨着springMVC,在博客里记录收获的点点滴滴。 但我还是坚持下来了,然后开始接触erp和鹏讯通系统。这时候我发现它与之前所做的报表截然不同,不再是冷冰冰的数据,而是企业命脉的体现。如果你不了解公司的业务逻辑,根本无从下手。于是一遍遍的跟相关部门的人沟通问题,整理需求。在这之中,我也开始思考,数据究竟是什么,有什么意义。对帆软提出的“让数据成为生产力”也有了一个模糊的认识。 在接下来的项目中,又接触到微信红包项目的报表开发。这是我第一次接触大数据级的项目,单表数据日增量300万+,基本的sql处理已经不能应付了,我开始学习使用kettle来处理数据。这又是一个没有接触过的工具,网上相关的资料和视频也不完整,相关的书籍也找不到,只能在百度那里搜索到一些零零散散的知识点,然后自己去摸索一个个功能的使用。在这个过程中,亲眼见证了一大堆毫无意义的数据在自己手里转化成一个个关键指标。 130210 微信红包扫码用户数6000万+,总扫码数12亿+,而且还在夜以继日的快速增长着,这些数据如果不经过处理,那么就丝毫没有意义,甚至还虚耗内存。但是经过处理,它就变成了帮助我们关键决策的一把利剑。通过分析消费者各时段的扫码量,可以创造更精准的广告营销。通过分析产品货龄,从而帮助企业优化调整铺货策略,使整个供应链的周转效率加快,降低过期和质量风险。通过扫码数量推算实际销量,可以实现对当地销售业绩预测以及对备案计划等起到了重要的参考价值。 这时候我也逐渐地认同了帆软,开始喜欢上了这个工具,决心深入的了解各个功能,因此我的能力也得到了不断的提高。 有一次领导提出了一个需求,要做一个防窜货报表。其中的一个难点是用到商户会员系统中的码表和扫码表,将扫码表的数据逐条遍历然后通过我们内部的一个算法找到对应的码表,再从码表里查出对应信息。当时负责这个系统的同事一听,拍拍手说“这个需求做不了”,但是我觉得还可以抢救一下,于是问他要了算法的代码,经过仔细的研读和分析之后,我有了一个大胆的想法,使用帆软的公式实现算法逻辑。后来几经试验,终于成功了。但是性能上不是很好,于是我开始寻找合适的替换方案,终于在kettle里使用java脚本来实现了。 在这过程中,我的能力也逐渐获得了领导的认同,从2016年底到2019年初,我收获了一次升职,多次调薪,并获得了公司的年度优秀员工。但更为重要的是,我从此坚定了自己的职业规划,不会再在内心徘徊。不管前方的道路有多难,我将在数据分析的路上继续奋斗。 2019年初,由于个人发展,我从东鹏饮料辞职,现就职于现代教育。 华山论剑,群雄争霸 江湖里有那么个地方,群贤毕至,高手云集,众人可以尽情展现自己的才艺,得到天下英雄的认可…… 130206 一千个读者就有一千个哈姆雷特 同样是finereport工程师,面对同一个问题,也可能有一千种想法,一千种方案。初学者可能想着的是如何解决问题,而优秀的人在想如何更好地解决问题。 2018年,我开始活跃于帆软论坛,加入了角逐问答的行列。 如果说,finereport如何入门最快,那无疑是看基础视频和帮助文档。如果说,如何快速深入掌握finereport,则应该是项目实战和问答。项目实战是技术+业务的结合体,而问答,则是脱离了业务,纯粹技术的体现。中国的应试教育非常强大,无数的学霸大佬都是在疯狂的刷题中成长起来。而帆软的问答,无疑是一个巨大的、实时更新的免费题库。不,是一个解答有回报的题库。 在问答里,隐藏着很多的大神,我常常为他们的答案惊叹不已。有很多问题的解答角度是自己从来都没有想过的,也不会去想的。遇到这些答案,我通常会拿来跟自己的进行比较,去劣存优,然后通过不断的学习,将它们转化为自己的知识点。而遇到暂时无法解决的问题时,我会把它们添加到收藏夹里,等以后有空了再翻出来看看。相信通过时间的积累,我将有更强的能力应付这些问题。 有一次遇到一个问题,要求实现点击当前分组时,当前分组数据的顺序改变,其他分组的顺序则保持不变。这几乎是一个不可能实现的问题,因为不同分组的数据,其实都是通过同一个字段扩展出来的,怎么可能实现一部分顺序改变,而另一部分不变呢。这令我百思不得其解,而社区里也有很多人都说不能实现。但我没有放弃,下班后一个人在办公室里默默的研究着,因为我在网页上见过类似的效果,而夜晚的静谧也为我打开了一条思路。我用一个数组里的下标来对应不同的分组,通过改变指定下标的值完成指定分组的顺序改变,最终实现了这个效果。这个方案也被我记在帮助文档《分组内排序互不干扰》里面。 130207 就这样日积月累,我也完成了华丽的转变。从一开始啥也不会的小菜鸟,到现在已经可以快速的响应别人的问题。更难得的是,在这之中,认识了论坛里面的许多好友,也得到了大家的认可,而由于全年的努力,官方也为我出了一篇专访。 归纳总结,秘籍传世 一代宗师,闭关苦修,终悟绝世武功,然不留下秘籍,竟至失传,悲乎哀哉…… 读书的时候,经常喜欢写点小东西,作文和周记也经常被老师拿来当堂朗读,文章上过校里面的专栏,也获得过市级的奖项。 毕业之后忙于工作,偶尔也喜欢在博客分享一下自己学习的过程。 一直觉得,写作是一个重新整理自己思路,归纳总结的过程。很多东西,也许我们当时记忆深刻,但是过不久便忘了。但是如果我们有过整理和记录,却是很难忘记。即使一时记不起来,回头看下当时的记录,记忆便一下子跃然于纸上。 在工作中,有一次用户反馈查询报表时报错,具体的报错信息是:错误代码......列表中的最大表达式数为 1000。报错信息很清楚,问题很容易定位,是下拉复选框选中的选项超过了一千个,导致Oracle的In语句查询的时候报错。但是怎么解决呢,当时查阅了帮助文档,确实有一篇对应的解决方案,先是用java自定义一个函数,然后在sql查询中嵌套帆软公式和自定义的函数,达到分隔字符串的目的。 当时看完这篇文档,脑子里只有一个想法,“太麻烦,不想动手”!但是问题不解决不行,于是只好自己想办法。这时我突然想到,可不可以用or语句来改写in语句呢,想到立刻便去验证,结果出人意料的简单,只需改一下sql和下拉框返回值的分隔符就能实现。 我把我的想法跟领导说了,当即收到了表扬,心里面很高兴,就想把解决方案记录下来,这时我了解到,原来帆软的帮助文档是人人都可以参与编辑的,于是我发布了自己的第一篇帮助文档。 后来每当有新的想法和方案,我都会将它整理下来,发布到帮助文档上。截至目前为止,已经发表了48篇文档。相信通过整理和总结,可以巩固自己的知识点。也希望自己的方案,能够给别人以帮助。 130208 兼收并蓄,和而大同 天下武功出少林,武学之间,本没有派系,唯有取长补短,方能更强…… FineReport,不止是FineReport。 帆软的使用过程中,涉及到的技术很多,sql、js、java、html等等。选择帆软,并不是与编程分道扬镳(并不会解决中年脱发烦恼)。好的编程功底,会在报表开发的路上助你一臂之力。 而今的我,早已不惧报表开发过程中的种种问题,甚至还能享受其中带来的乐趣。但是依然觉得,需要学习的知识还有很多,比起那些优秀的人来,我还差得很远。选择了这一行,就注定要学习一辈子,奋斗一辈子。 但我不怕奋斗。未来的路还很长,我将不忘初心,砥砺前行。 期待与你一起进步! 130211
一见帆软误终生,从此java是路人
说起跟帆软的缘分,还是非常偶然的。2016年9月,刚刚毕业的我辗转一段时间后来到如今任职的公司——东鹏饮料(集团)股份有限公司(当时名称为深圳市东鹏饮料实业有限公司),职位是一名程序员,负责泛微oa流程开发方面工作。那时候帆软跟我们公司签约还不久,有两名帆软员工在现场实施项目,而我们公司这一块还没安排人员负责,于是在一次部门会议上,我就被安排负责帆软报表项目开发,那是我第一次听到finereport这个名词。 第一眼看到帆软设计器时,给我的感觉就是“这不是一个Excel吗”。带着这份感觉,我花了一个上午看了susie大美女的入门视频,下午又把帮助文档的初级教程刷了一遍,再顺手做了几个例子。第二天我对领导说,差不多了,可以给个任务试试水了。当天下午就给我安排了一个人力资源相关的报表,并说看看明天中午之前能不能弄出来,结果当天下午就弄出来了,这个时候我的感觉是双重的,一方面为自己提前完成工作而高兴,另一方面又在担心,这么简单的工作,就这么干下去,有没有前途呢? 犹豫归犹豫,生活还要继续。就这样我渐渐的接管了报表项目的所有相关工作。也是随着时间的推移,我逐渐的意识到了,finereport入门超简单,但要深入真的很难。这个时候我开始接触到了帆软社区,每天都会到论坛上逛一下帖子,尝试着解答别人的问题,发现自己很多问题都不会,而很多大神的解答往往令我耳目一新。我意识到了自己的不足,要学习的还很多,于是很多时候我都泡在论坛的帖子和帮助文档里。这时候公司的工作也开始加重,从一开始对接一两个项目的报表开发,到现在对接十来个项目,直连数据库多达22个,部分项目外包给其他公司来负责开发的,连一份数据字典都没有,沟通起来又困难,大部分时间都是自己一个人在处理,从需求沟通、数据处理、报表开发、后期运维全部一手包揽。也因如此,获得了公司2017年度的优秀员工。118310 118312 2018年开始活跃在帆软社区,1月升级为互助专家,7月升级为互助叫兽。截至目前解决了672个问题,采纳率达到50%。创建帮助文档24篇,编辑文档43篇,其中20篇被选为优秀文档。 118241 118242118313此外,还有帮助文档任务,和之前的小帆知识活动也做了一点贡献。 118243 118244截至目前为止,除了一些接口和几个自定义函数的开发外,已经有两年多没碰过java了,忘得差不多了。希望明年重温一下,涉足插件开发领域。。。。。。{:fange09gif:} 最后介绍一下本人,姓钟,名星启,启明星的星,启明星的启。希望认识更多的论坛好友。 附上照骗一张(两年前万圣节拍的,现在虚长了一些肉,就不辣眼睛了){:4_846:} 118336 编辑于 2018-9-20 12:39 编辑于 2018-9-20 15:42
献给七夕默默工作的小番薯
昨天有个妹子跟我说 七夕了做报表的都不懂浪漫的吗 (纯属意淫) {:fange04gif:} 于是造了些数据,搞了个流向地图 114218 感觉太丑了就不放模板板块了 114219
3D炫酷卡片翻转报表
关于有图片的报表的设计,如果设计成行式报表,图片占据行高太高,页面不美观 {:10_296:} 传统的卡分栏报表看着也挺枯燥 就不多说,来感受3D动态翻转报表吧。 编辑于 2018-4-6 15:14
截图纪念一下
光棍时刻。 99022 希望下一刻起,光棍时刻一去不复返。 编辑于 2018-3-27 22:18
使用js实现时钟效果
前段时间逛论坛的时候,发现了这个帖子 FineReport V8.0 插件开发之酷炫时钟控件http://bbs.fanruan.com/thread-66972-1-1.html 效果好酷啊有木有,遗憾的是帖子中的链接已经失效了,在插件商场中也找不到相关的插件。 于是就想自己动手用js写一个。 首先在单元格中输入下面的代码,然后使用html显示内容。 这个宽高可以根据自己需要填。 92322 然后在预览方式中添加加载结束事件:var dom=document.getElementById("view"); //获取canvas元素 var ctx=dom.getContext("2d"); //创建context对象 var width=ctx.canvas.width; var height=ctx.canvas.height; var r=width/2; //绘制时钟背景 function drawBackground(){ ctx.translate(r,r); //将画布原点重置为画布的中心 ctx.beginPath(); ctx.lineWidth=10; ctx.arc(0,0,r-5,0,2*Math.PI); //绘制一个圆,即时钟的边框 ctx.stroke(); //绘制时钟上的刻度 for(var i=0;i<60;i++){ var x=(r-20)*Math.cos(Math.PI*2/60*i); var y=(r-20)*Math.sin(Math.PI*2/60*i); //每逢5个刻度使用黑色绘制,其余用灰色绘制 if(i%5===0){ ctx.fillStyle="#000000"; }else{ ctx.fillStyle="#cccccc"; } ctx.beginPath(); ctx.arc(x,y,5,0,2*Math.PI); ctx.fill(); } //绘制时钟上的数字 ctx.font="20px Arial"; ctx.textAlign="center"; ctx.textBaseline="middle"; ctx.fillStyle="#000000"; for(var j=0;j<12;j++){ var ax=(r-50)*Math.cos(Math.PI*2/12*j); var ay=(r-50)*Math.sin(Math.PI*2/12*j); ctx.beginPath(); ctx.fillText(j>9?j-9:j+3,ax,ay); //因为PI的角度计算是从3点钟方向顺时针计算的,所以要对数字判断处理 ctx.fill(); } } //绘制时针 function drawHour(hour,minute,second){ ctx.save(); //保存当前绘图环境 ctx.beginPath(); //时针的角度等于小时的角度加分钟和秒钟转化为小时的角度 var rad=2*Math.PI/12*hour+2*Math.PI/12/60*minute+2*Math.PI/12/60/3600*second; ctx.rotate(rad); ctx.lineWidth=14; ctx.lineCap="round"; //设置画线结束端为圆帽形 ctx.moveTo(0,20); ctx.lineTo(0,-r+100); ctx.stroke(); ctx.restore(); //返回之前保存的绘图环境 } //绘制分针 function drawMinute(minute,second){ ctx.save(); //保存当前绘图环境 ctx.beginPath(); //分针的角度等于分钟的角度加秒钟转化为分钟的角度 var rad=2*Math.PI/60*minute+2*Math.PI/3600*second; ctx.rotate(rad); ctx.lineWidth=10; ctx.lineCap="round"; ctx.moveTo(0,20); ctx.lineTo(0,-r+80); ctx.stroke(); ctx.restore(); //返回之前保存的绘图环境 } //绘制秒针 function drawSecond(second){ ctx.save(); //保存当前绘图环境 ctx.beginPath(); ctx.fillStyle="#FF0000"; var rad=2*Math.PI/60*second; //秒针的角度为当前秒钟的角度 ctx.rotate(rad); ctx.lineWidth=2; ctx.lineCap="round"; ctx.moveTo(0,30); ctx.lineTo(8,0); ctx.lineTo(0,-r+30); ctx.lineTo(-8,0); ctx.lineTo(0,30); ctx.fill(); ctx.restore(); //返回之前保存的绘图环境 } //重新绘制时钟 function run(){ ctx.clearRect(0,0,width,height); //清空整张画布,在下面的代码中重新绘制 ctx.save(); //保存当前绘图环境 var time =new Date(); //获取当前时间 var hour=time.getHours(); //获取小时数 var minute=time.getMinutes(); //获取分钟数 var second=time.getSeconds(); //获取秒数 drawBackground(); //绘制背景 drawHour(hour,minute,second); //绘制时针 drawMinute(minute,second); //绘制分针 drawSecond(second); //绘制秒针 //绘制时钟中心的那个点 ctx.fillStyle="#555"; ctx.beginPath(); ctx.arc(0,0,8,0,2*Math.PI); ctx.fill(); ctx.restore(); //返回之前保存的绘图环境 } window.setInterval(function(){run();},1000); //每隔一秒重新绘制时钟 如果是在表单中,就添加报表块然后执行相同操作,然后在报表块的事件里把上述js代码添加到下面代码的function里面 setTimeout(function(){ },1000);最后上个效果图:92323 93366 93367 添加注释 添加模板 编辑于 2018-1-15 21:30 编辑于 2018-1-23 18:42 编辑于 2018-1-27 16:51 编辑于 2018-1-27 16:54
Oracle数据库基础
整理文件发现自己之前刚学Oracle时整理的sql基础,分享下。 -- number -10 38次方--- 10 38次方 char 定长,最多存储2000字符,查询效率高 varchar2 可变长,最多存储4000字符,查询效率低 clob 最大存储4G blob 存储二进制数据,4G 创建表 create table ( 字段 数据类型 , 字段 数据类型 , 字段 数据类型 ) 修改表的操作 添加字段 alter table add (字段名,数据类型) 删除字段 alter table drop column 修改字段 alter table modify (字段名,数据类型) 给已有的表重命名 rename to 添加主键 alter table add constraint primary key(字段);--如果有多个,称之为联合主键 添加外键 alter table add constraint foreign key (从表名的外键字段) references 主表(主键字段) on delete cascade 删除约束 alter table drop constraint 创建表 create table as select * from -- 复制表2 create table as select * from where 1=2 --复制表结构 create table as select , from 插入数据 insert into values (值1,值2,.......值n); insert into (字段1,字段2,....字段n) values (值1,值2,.......值n); insert into select from where 字段='值'; insert into () select from where 字段='值'; insert all into values (1004,'haha') into values (1005,'heihei') select * from dual; ---删除数据 delete from where 字段='值'; --速度慢,要写日志:把日志写在回滚表中 truncate table --速度快,不需要写日志 drop table drop user cascade drop view 修改数据 update set ='值' where 字段='值'; update set ='值' and ='值' where 字段='值'; 查询数据 select 字段1,字段2,......字段n from ; select 字段1,字段2,......字段n from where 字段='值'; select 字段1,字段2,......字段n from (select 字段1,字段2,......字段n from where 字段='值' ) where 字段='值' select 字段1,字段2,......字段n from where 字段 = select 字段1 from ; 组函数--聚合函数 MAX,MIN,AVG,COUNT,SUM 常用的函数 substr() upper() lower() instr() lpad() rpad() trim() to_char() to_date() trunc() round() nvl() nvl2() initcap() next_day() length() replace() mod() ------------------ case when 表达式 then 值1 when 表达式 then 值2 else 默认值 end decode(字段, '值1','值1结果', '值2','值2结果', '值3','值3结果', '默认值' ) -----case 和 decode 区别:decode只能判断等值的表达式 case可以判断区间表达式 联合查询 左连接: select * from left outer join on 表名1.字段=表名2.字段 select * from , where 表名1.字段=表名2.字段(+) 右连接 select * from right outer join on 表名1.字段=表名2.字段 select * from , where 表名1.字段(+)=表名2.字段 全链接 select * from full outer join on 表名1.字段=表名2.字段 ---去重复,(有重复的数据只显示一次) select * from emp20 union select * from emp ---不去重复(有重复的数据全部显示) select * from emp20 union all select * from emp ---(差集) select * from emp20 minus select * from emp ---交集 select * from emp20 intersect select * from emp 分组:group by 排序:order by desc降序 默认升序 asc 分组之后过滤:having 单行过滤:where select * from emp where ..... group by ..... having ...... order by ..... 使用 group by 要注意的事项: select 后面的字段必须由:组函数或者是分组的字段 ---分页 select * from (select rownum no, e.* from (select * from emp order by sal desc) e where rownum 1; --- 创建视图 CREATE VIEW view AS subquery OR REPLACE表示如果视图已经存在则重新创建 FORCE表示创建视图而不管基表是否存在,NOFORCE表示只有基表存在的情况下才创建视图(默认情况) view表示视图名 aliaslist表示别名列表(别名之间用逗号隔开,别名的个数需要和子查询中选择的字段或表达式的个数一致) subquery表示子查询 WITH CHECK OPTION表示只有可访问的行在视图中才能被插入或更新 cname表示为约束指定的名称 WITH READ ONLY表示在该视图中不可执行DML操作 insert into values('值1','值2',.....'值n');//此数据插入视图对应的表中 update set = '值' where = '值'; delete from where = '值'; 如果视图中包含下面的内容,就不可以从视图中删除数据 组函数 GROUP BY子句 DISTINCT关键字 伪列ROWNUM关键字 如果视图中包含下面的内容,就不可以在视图中更新数据: 组函数 GROUP BY子句 DISTINCT关键字 伪列ROWNUM关键字 用表达式定义的字段 如果视图中包含下面的内容,就不可以在视图中插入数据: 组函数 GROUP BY子句 DISTINCT关键字 伪列ROWNUM关键字 用表达式定义的字段 基本中的NOT NULL字段不在视图中 /* 创建序列 */ create sequence seq_semple increment by 1 start with 1 maxvalue 9999 nocycle nocache -- 修改序列 alter sequence seq_semple increment by 2 maxvalue 9999 nocycle nocache insert into test values(seq_semple.nextval,'小明','123'); insert into test values(seq_semple.nextval,'小花','1234'); insert into test values(seq_semple.nextval,'小丽','234'); insert into test values(seq_semple.nextval,'小红','12345'); commit; select * from test; select seq_semple.nextval, seq_semple.currval from dual; select seq_semple.currval from dual; --删除序列 drop sequence seq_semple; /* 索引 */ --创建索引 create table t( tid number primary key, tname varchar2(20), tel number unique not null--默认自动创建索引 ) --创建索引 create index i_test1 on test(tname,tpsw) --删除索引 drop index i_test1; --系统权限 create user jm identified by jm123; create user tom identified by tom123; --让用户jm需要登录;并且让用户同时具有赋权限的功能 grant create session to jm with admin option --让jm给tom赋权限(登录) grant create session to tom; --收回jm的登录权限,但是,tom依然可以登录;(不是级联回收) revoke create session from jm; --对象权限 emp表在scott【方案】,给mqx用户赋予访问(select)emp表的权限 grant select on scott.emp to mqx; --给jm赋予查emp表的权限,同时权限下放 grant select on scott.emp to jm with grant option; grant select on scott.emp to tom; --回收jm的访问emp表的权限(tom不能访问到emp表,证明是级联回收) revoke select on emp from jm; --如何创建角色 create role joy; --给角色授权 grant create table,create view,create sequence, create procedure to joy; --给用户授予角色 grant joy to jm; --创建存储过程 --public void show(){System.out.println();} create or replace procedure p_pro is begin insert into test values(2,'狗狗','234'); end; --执行存储过程 begin p_pro; end; /*public static void show(String msg){ System.out.println(msg); } public static void main(String args){ String msg = "Hello World"; show(msg); } */ --有参数的存储过程 create or replace procedure sp_pro( iid number, iname varchar2, ipass varchar2 ) is begin insert into test values(iid,iname,ipass); end; --执行存储过程 begin sp_pro (3,'猪猪','345'); end; --根据ID查找动物的名字; create or replace procedure sp_p ( iid in number, outname out varchar2, outtpsw out number ) is begin select tname,tpsw into outname,outtpsw from test where tid=iid; end sp_p; /* int i =0; String str = "a"; String s; Scanner input = new Scanner(System.in); s = input.next(); */ declare oname varchar2(20);--接受返回来的值 outpsw varchar2(20); iid number:='&请输入要查询的ID'; begin sp_p(iid,oname,outpsw); dbms_output.put_line('动物的名称:'||oname||'动物的编号:'||outpsw); --System.out.println("Hello World!"); exception when no_data_found then dbms_output.put_line('朋友输入的数据有误,请重新输入'); end; commit; select * from test; truncate table test; --删除存储过程 drop procedure ; --查询所有存储过程 select * from user_objects where object_type='PROCEDURE'; --创建函数 create or replace function f_m1 return varchar2 is begin return '我真是一个天才啊!'; end; /* public String findById(int id){ String msg=null; if(id==1){ msg="星期一"; }else if(id==2){ msg="星期二"; } return msg; } */ --执行函数 select f_m1 from dual; create or replace function f_m2(idd number) return varchar2 is outname varchar2(20); begin select tname into outname from test where tid=idd; return outname; end; --执行函数【命令窗口执行】 var sname varchar2; call f_m2(2) into:sname; --查询所有函数名称 select object_name from user_objects where object_type='FUNCTION'; --创建触发器 create or replace trigger t_test before insert on test for each row begin --dbms_output.put_line('用户名'|| :new.tname); --dbms_output.put_line('密码'|| :new.tpsw); insert into msgtable values (seq_se.nextval,'宠物名:'||:new.tname||'宠物编号'||:new.tpsw); end; --调用存储过程向test表中插入数据 begin sp_pro(13,'美国摩登考拉No.1','888'); end; alter table msgtable modify (msg varchar2(50)); commit; --删除触发器 drop trigger t_test; select * from msgtable; /* 游标 */ declare cursor cul is select * from test; srow test%rowtype; begin open cul; fetch cul into srow; while cul%found loop dbms_output.put_line(srow.tid||srow.tname||srow.tpsw); fetch cul into srow; end loop; close cul; end; declare v_num number:=10086; v_context varchar2(20) default '本人很聪明!'; v_ip constant number(3,1):=10.1; v_sal emp.sal%type; v_emp emp%rowtype; begin v_context:='我们都是好孩子'; dbms_output.put_line(v_context); end; declare v_row emp%rowtype; begin select * into v_row from emp where empno = 7369; dbms_output.put_line(v_row.ename); end; declare age number:= 20; begin age:='&请输入你的年龄'; if age<20 then dbms_output.put_line('我还不够法定结婚年龄!'); else if age >22 then dbms_output.put_line('我刚大学毕业!'); else dbms_output.put_line('我该的啦!'); end if; end if; end;
连续区间求值方案
今天在逛论坛的时候发现了这个帖子:怎么实现这个呢,有没有什么模板可以参考一下的呢。咋一看,正好跟前几天同事发给我看的那个sql题十分相似 82920 于是趁着今晚美好的月光,咳咳,写了这篇文档。 先抛开sql不提,帆软设计器其实为我们这种需求提供了一个很方便的方法,那就是相邻连续分组 82914 这里面采用的数据就是上面NBA球队的数据,第一列数据放的是球队名,设置为分组-相邻连续,后面三列都放年份,设置分别为汇总-最小值,汇总-最大值,汇总-个数。预览效果如下: 82915 然后我们在年份那一列设置条件属性如下,就可以实现只展示连续夺冠的队伍: 82916 82917 在这里附上模板82918 好,说完了设计器,我们回到sql上,当数据量比较少时,利用设计器的功能即方便又快速,如果数据量比较大,我们还是用sql处理比较好。 这里以Oracle为例,因为我之前搞出这个sql时,写了一篇解决的思路,这里就不赘述了,直接上最终sql: select team,min(y),max(y),count(1) from ( select team,y,sum(b)over(order by y)c from ( select team,y, case when team=lag(team)over(order by y) then 0 else 1 end as b from nba)) group by c,team having count(1)>1 order by c效果如下: 82919 顺便说下,表结构就两个字段,team是队名,Y是年份。 另外,如果想清楚思路的话,可以看我的博客:Oracle求连续区间最大最小值
最新jar无法在同步用户中导入树数据集
产品建议:超链接打开方式
70787
插件开发文档看不了
69943
教小帆说话中的文本域不是富文本啦
如图:上面的那些插入图片,设置格式的选项都不见了 69717
Oracle参数个数限制的解决方法
好久之前就有遇到这个问题,使用Oracle查询的时候,参数设置为下拉多选框,经常会有参数个数限制问题 69686 后来查阅文档,发现有一篇自定义函数的文档可以解决这个问题:SubSection函数-Oracle查询参数个数限制。但是这个办法好麻烦有木有啊,而且小白多半看不懂。今天有人跟我说他想用js实现将下拉框返回值分层,结果测试不行。但我突然灵光一闪,sql查询不是可以使用or代替in吗?带着这个疑惑,我亲自测试了下,结果成了,好激动。具体实现如下: SQL:select * from table where id=${id}将参数id设置成下拉多选框并设置数据字典,接下来是重点,设置分隔符:69687没了,没了,你没看错,这就结束了,就是这么简单,预览查询,成功!另外,我刚刚编辑了文档:Oracle多值查询参数个数限制,还没审核,不懂你们能不能看{:4_841:} {:4_844:} {:4_847:}
上传图片弹出框中的按钮不见了
如图,这个位置的按钮看不见了,但点击还是有效果的。 69189
教小帆说话中插入图片没内容了
我输入了文字和插入图片,然后保存,就显示这个样子: 68892 点击编辑内容也是0。
粘贴的图片出不来
如图,粘贴的图片出不来,而且鼠标滚轮往下滚会出现越来越多的加载圈……截图只粘贴了一个图,本帖用的是上传图片 68240
【已解决】签到签不了,上传图片也不行
签到和上传图片都不行,显示错误:内部错误,无法显示此内容{:10_289:}
输入法乱飘
无论在哪里打字,输入法一下子在左上角,一下子又飘到右下角,好烦,有此BUG的番薯们点下赞,及早修复6309263093
12下一页
个人成就
内容被浏览682,691
加入社区7年177天
返回顶部