介绍
写sql字段太多核对编写起来太累了,公司项目又紧,一星期3000多行sql,要各种转换调用各种接口,所以为了提高工作效率,争取更多时间(摸鱼),我就用python了,相对于其它重复的敲小伙伴,我就直接飞起,现向大家展示个人比较常用的编写sql的代码
1.字段取别名
如果还在手动的赋值粘贴表别名,你就累了,我直接反手一正则
import re
table_AS = 'td.'
schema = '[dbo].'
SQL = f"""SELECT {table_AS}Id,CreateTime,shenpibianma,xingming,gonghao,bumen,shenpizhuangtai,wanchengshijian,zhuti,feiyongbaoxiaozonge,beizhu,fujian
"""
print(re.sub(',', f',{table_AS}', str(SQL), SQL.count(',')))
运行结果:
SELECT td.Id,td.CreateTime,td.shenpibianma,td.xingming,td.gonghao,td.bumen,td.shenpizhuangtai,td.wanchengshijian,td.zhuti,td.feiyongbaoxiaozonge,td.beizhu,td.fujian
re模块中的sub类似于字符串函数replace匹配进行替换
语法re.sub(pattern,repl,string,count);
pattern:正则中的模式字符串,repl:要替换的字符串,string:原始字符串,count:替换几次
而str.count(',')就是在统计逗号出现的次数,进而对应sub函数的替换次数
2.CASE WHEN批量转换
data_value = "我是谁,ice,_,Seattle"
field_name = 'Demo_test'
data_value = data_value.split(',')
index_range = len(data_value)
sql = ['']
def case_when():
for i in range(0, index_range - 1):
sql.append('')
for i in range(0, index_range, 1):
sql[i] = f""" WHEN {field_name} = '{i}' THEN '{data_value[i]}' \n"""
return ''.join(map(str, sql))
运行结果:
CASE
WHEN Demo_test = '0' THEN '我是谁'
WHEN Demo_test = '1' THEN 'ice'
WHEN Demo_test = '2' THEN '_'
WHEN Demo_test = '3' THEN 'Seattle'
ELSE '请选择' END Demo_test,
以为很方便,确实很方便,结合起来更方便,对于特殊情况,例如case when中出现 or 或 and,
PATINDEX('%[^0-9|.|-|+]%', 字段)=0 THEN (SELECT Name FROM Areas where ID = 字段)
等可以根据具体情况进行更改
3.批量生成表名,字段名系列
实现逻辑,通过sql语句查询系统中的所有表名,字段名,格式化输出成需要的格式进行输出,此处用的正则,其中/..../g表示全文匹配,此处用的sql server
其中使用
SELECT NAME FROM SYSOBJECTS WHERE XTYPE='u' 获取数据库中所有表名
select name from syscolumns where id=(select max(id) from sysobjects where xtype='u' and name = '数据表') 获取所查表的所有字段名
import re
import pymssql
server = '192.168.10.10'
user = "账号"
password = "密码"
database = "数据库"
connect = pymssql.connect(server, user, password, database)
cursor = connect.cursor()
cursor.execute("select name from sysobjects where xtype='u'")
# print(cursor.fetchall())
Data_Tab = cursor.fetchall()
data_table = re.sub('[/\\[\\](,)\'*/g]', f'', str(Data_Tab))
print(re.sub('[/ /g]', f'\n', str(data_table)))
'''
for i in range(0, len(list_data)):
print(list_data[i])
'''
# 获取指定表列名
cursor.execute("select name from syscolumns where id=(select max(id) from sysobjects where xtype='u' and name = 'Areas')")
Data_Col = cursor.fetchall()
data_column = re.sub('[/\\[\\]()\'*/g]', f'', str(Data_Col))
print(data_column.replace(',,', ','))
运行结果如下,数据表很多只列举部分
RF_ProramButton
RF_ProramExport
RF_ProramField
RF_ProramQuery
RF_ProramValidate
RF_SystemButton
RF_Test
RF_Test1Sub
RF_TestSub
RF_UserFileShare
RF_UserShortcut
RF_Vote
RF_VoteItem
RF_VoteItemOption
RF_VotePartakeUser
RF_VoteResult
RF_VoteResultUser
RF_WorkDate
RF_WorkGroup
RF_DbConnectionID, ParentId, ReionId, Name, MererName, ShortName, MererShortName, LevelType, CityCode, ZipCode, Pinyin, Jianpin, FirstChar, Ln, Lat, Remark, Order, IsDelete, InsertTime,
这样在写程序SQL对应字段编写中就会很快,与其它小程序可以灵活搭配
4.数字加引号
def use_re(e):
value = int(e.group('value'))
return f"'{str(value)}'"
sql = """
case
when Staff_Category = 1 then '请选择'
when Staff_Category = 2 then '试用期员工'
when Staff_Category = 3 then '正式员工'
when Staff_Category = 5 then '劳务(全职)'
when Staff_Category = 6 then '劳务(兼职)'
when Staff_Category = 7 then '岗位外包'
when Staff_Category = 9 then '劳务(临时工)'
when Staff_Category = 10 then '返聘'
when Staff_Category = 11 then '特聘'
else '' end Staff_Category
"""
elements = re.sub('(?P<value>\\d+)', use_re, ''.join(map(str, sql)), count=0, flags=0)
print(f'{elements}')
正则\d匹配数字类型,pycharm中用\\d表示,将sql粘贴在sql区域内就可以批量对数字加引号,对于前后端的类型转换是有用的
运行结果如下
case
when Staff_Category = '1' then '请选择'
when Staff_Category = '2' then '试用期员工'
when Staff_Category = '3' then '正式员工'
when Staff_Category = '5' then '劳务(全职)'
when Staff_Category = '6' then '劳务(兼职)'
when Staff_Category = '7' then '岗位外包'
when Staff_Category = '9' then '劳务(临时工)'
when Staff_Category = '10' then '返聘'
when Staff_Category = '11' then '特聘'
else '' end Staff_Category
5.sql字段多值截取
在数据库中会遇到一个字段存储的值为 1,3,2等,对于case when输出展示在系统上判断在不在('1','2','3')并不友好,而stuff()也不能解决这种情况,需要substring()与charindex()结合使用,其中
CHARINDEX(substring, string [, start_location])
substring为要搜的字符串,string为被搜索的字符串,此处用的数据表字段
start_location参数可选,为搜索起始位置
对此我针对这一类问题写了截取 判断 in (范围)的情况
import re
def use_re(e):
value = int(e.group('value'))
return f"'{str(value)}'"
field = 'seal'
values = '2,4,7,8'
index_range = 1
sql = ['']
for i in range(0, len(values) - 1):
sql.append('')
for i in range(0, len(values), 2):
sql[i] = f"""SUBSTRING({field}, charindex({values[i]},{field}), {index_range}) not in ({values}) AND \n"""
elements = re.sub('(?P<value>[2-9]+)', use_re, ''.join(map(str, sql)), count=0, flags=0)
print(f'{elements}')
运行效果如下
SUBSTRING(seal, charindex('2',seal), 1) not in ('2','4','7','8') AND
SUBSTRING(seal, charindex('4',seal), 1) not in ('2','4','7','8') AND
SUBSTRING(seal, charindex('7',seal), 1) not in ('2','4','7','8') AND
SUBSTRING(seal, charindex('8',seal), 1) not in ('2','4','7','8') AND
以上就是五种常用小模块,后续会写在图形界面上