1 ORM常用操作
1.1 概念
ORM機制
對象關系映射(英語:Object Relational Mapping,簡稱ORM),用于實現面向對象編程語言里不同類型系統的數據之間的轉換。換句話說,就是用面向對象的方式去操作數據庫的創建表,增加、修改、刪除、查詢等操作。
1.2 查看ORM生成的sql語句。
1.2.1 使用QuerySet中的query屬性
user_list = User.objects.all()
print(user_list.query)
1.2.2 使用Logging日志查看
前面有提及,此處略
1.3 ORM優缺點
1.3.1 優點
- ORM使得我們的通用數據庫交互變得簡單易行,并且完全不用考慮該死的SQL語句。快速開發,由此而來。
- 可以避免一些新手程序猿寫sql語句帶來的性能效率和安全問題:select * from table效率低,避免sql注入風險
1.3.2 缺點
- 性能有所犧牲,不過現在的各種ORM框架都在嘗試使用各種方法來減輕這個問題(LazyLoad,Cache),效果還是很顯著的。
- 對于個別復雜查詢,ORM仍然力不從心。為解決這個問題,ORM框架一般也提供了直接寫原生sql的方式。
1.4 ORM 機制下面的增刪查改操作
本次所有的實驗測試都在manage.py的shell模式下面進行操作,建議安裝IPython提高交互
進入Shell編輯界面
D:\virtualenv\env_py35_django\Scripts>activate
(env_py35_django) D:\virtualenv\env_py35_django\Scripts>cd D:\MaiZi_Edu\Dropbox\Maizi\Django\learn11_22\hello_django
(env_py35_django) D:\MaiZi_Edu\Dropbox\Maizi\Django\learn11_22\hello_django>python manage.py shell
Python 3.5.1 (v3.5.1:37a07cee5969, Dec 6 2015, 01:54:25) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>>
安裝IPython的編輯器,提供更為強大的編輯和交互功能。
安裝IPython后的編輯界面
(env_py35_django) D:\MaiZi_Edu\Dropbox\Maizi\Django\learn11_22\hello_django>pip install ipython
Successfully installed appdirs-1.4.0 colorama-0.3.7 decorator-4.0.11 ipython-5.2.2 ipython-genutils-0.1.0 packaging-16.8 pickleshare-0.7.4 prompt-toolkit-1.0.13 pygments-2.2.0 pyparsing-2.1.10 setuptools-34.1.1 simplegeneric-0.8.1 traitlets-4.3.1 wcwidth-0.1.7 win-unicode-console-0.5
(env_py35_django) D:\MaiZi_Edu\Dropbox\Maizi\Django\learn11_22\hello_django>python manage.py shell
Python 3.5.1 (v3.5.1:37a07cee5969, Dec 6 2015, 01:54:25) [MSC v.1900 64 bit (AMD64)]
Type "copyright", "credits" or "license" for more information.
IPython 5.2.2 -- An enhanced Interactive Python.
? -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help -> Python's own help system.
object? -> Details about 'object', use 'object??' for extra details.
In [1]:
注意:每次退出shell模式都要重新導入 from hello.models import *
1.4.1 增
- 插入簡單數據:
In [1]: from hello.models import *
In [2]: Author.objects.create(name='藍盾')
(0.000) BEGIN; args=None
(0.033) INSERT INTO "hello_author" ("name") VALUES ('藍盾'); args=['藍盾']
Out[2]: <Author: 藍盾>
create的方法插入簡單數據
- 插入一對多關系數據:使用create方法,外鍵的字段輸入的是對應外鍵的id值
In [4]: AuthorDetail.objects.create(sex=False,email='landun@landun.com',address='www.landun.com',birthday='2017-1-19',author_id=4)
(0.000) BEGIN; args=None
(0.001) INSERT INTO "hello_authordetail" ("sex", "email", "address", "birthday", "author_id") VALUES (0, 'landun@landun.com', 'www.landun.com', '2017-01-19', 4); args=[False, 'landun@landun.com', 'www.landun.com', '2017-01-19', 4]
Out[4]: <AuthorDetail: www.landun.com>
create的方法插入一對多關系數據
- 通過對象的方法插入數據:實例化對象,給對象加入屬性,通過save方法保存
In [5]: pub = Publisher()
...: pub.name = "電子工業出版社"
...: pub.address = "廣東廣州"
...: pub.city = "廣州"
...: pub.state_province = "廣州"
...: pub.city = "廣東"
...: pub.country = "中國"
...: pub.website = "http://www.baidu.com"
...: pub.save()
...:
(0.000) BEGIN; args=None
(0.001) INSERT INTO "hello_publisher" ("name", "address", "city", "state_province", "country", "website") VALUES ('電子工業出版社', '廣東廣州', '廣東', '廣州', '中國', 'http://www.baidu.com'); args=['電子工業出版社', '廣東廣州', '廣東', '廣州', '中國', 'http://www.baidu.com']
通過對象的方法插入數據
- 通過對象的方法插入多對多的數據:通過get方法獲取兩個對象的實例,然后再用add方法來關聯他們之間的關系
In [6]: Book.objects.create(title='Pytho實戰',publisher=pub,publication_date='2015-5-6')
(0.000) BEGIN; args=None
(0.001) INSERT INTO "hello_book" ("title", "publisher_id", "publication_date", "price") VALUES ('Pytho實戰', 8, '2015-05-06', '10.00'); args=['Pytho實戰', 8, '2015-05-06', '10.00']
Out[6]: <Book: Pytho實戰>
In [7]: book = Book.objects.get(id=1)
(0.001) SELECT "hello_book"."id", "hello_book"."title", "hello_book"."publisher_id", "hello_book"."publication_date", "hello_book"."price" FROM "hello_book" WHERE "hello_book"."id" = 1; args=(1,)
In [8]: author = Author.objects.get(id=1)
(0.000) SELECT "hello_author"."id", "hello_author"."name" FROM "hello_author" WHERE "hello_author"."id" = 1; args=(1,)
In [9]: book.authors.add(author)
(0.000) BEGIN; args=None
(0.000) SELECT "hello_book_authors"."author_id" FROM "hello_book_authors" WHERE ("hello_book_authors"."book_id" = 1 AND "hello_book_authors"."author_id" IN (1)); args=(1, 1)
通過對象的方法插入多對多的數據
1.4.2 刪【級聯刪除】
使用filter方法過濾在用delete刪除,注意所有的刪除都是級聯刪除
In [10]: Book.objects.filter(id=13).delete()
(0.000) SELECT "hello_book"."id", "hello_book"."title", "hello_book"."publisher_id", "hello_book"."publication_date", "hello_book"."price" FROM "hello_book" WHERE "hello_book"."id" = 13; args=(13,)
(0.000) BEGIN; args=None
(0.001) DELETE FROM "hello_book_authors" WHERE "hello_book_authors"."book_id" IN (13); args=(13,)
(0.048) DELETE FROM "hello_book" WHERE "hello_book"."id" IN (13); args=(13,)
Out[10]: (1, {'hello.Book': 1, 'hello.Book_authors': 0})
delete的方法刪除
1.4.3 查【惰性查詢】
- 惰性查詢:直到使用的時候才會對數據庫進行查詢
- shell下面是非惰性的,py文件下面都是惰性查詢
- 查詢使用filter得到的是QuerySet對象,使用get芳芳得到的是一個models對象
In [11]: Book.objects.filter(id=1)
Out[11]: (0.001) SELECT "hello_book"."id", "hello_book"."title", "hello_book"."publisher_id", "hello_book"."publication_date", "hello_book"."price" FROM "hello_book" WHERE "hello_book"."id" = 1 LIMIT 21; args=(1,)
[<Book: 第一本《Python web 開發》>]
In [13]: type(Book.objects.filter(id=1))
Out[13]: django.db.models.query.QuerySet
In [12]: Book.objects.get(id=1)
(0.000) SELECT "hello_book"."id", "hello_book"."title", "hello_book"."publisher_id", "hello_book"."publication_date", "hello_book"."price" FROM "hello_book" WHERE "hello_book"."id" = 1; args=(1,)
Out[12]: <Book: 第一本《Python web 開發》>
In [14]: type(Book.objects.get(id=1))
(0.001) SELECT "hello_book"."id", "hello_book"."title", "hello_book"."publisher_id", "hello_book"."publication_date", "hello_book"."price" FROM "hello_book" WHERE "hello_book"."id" = 1; args=(1,)
Out[14]: hello.models.Book
使用filter和get方法進行查詢
1.4.4 改
- save的方法簡單修改表數據(get和save結合)
In [14]: author = Author.objects.get(id=4)
(0.001) SELECT "hello_author"."id", "hello_author"."name" FROM "hello_author" WHERE "hello_author"."id" = 4; args=(4,)
In [15]: print(author.name)
藍盾
In [16]: author.name = "藍視"
In [17]: author.save()
(0.000) BEGIN; args=None
(0.126) UPDATE "hello_author" SET "name" = '藍視' WHERE "hello_author"."id" = 4; args=('藍視', 4)
In [18]: print(author.name)
藍視
save的方法簡單修改表數據
- save的方法修改關聯表數據(get和save結合)
In [19]: authordetail =AuthorDetail.objects.get(author=author)
(0.001) SELECT "hello_authordetail"."id", "hello_authordetail"."sex", "hello_authordetail"."email", "hello_authordetail"."address", "hello_authordetail"."birthday", "hello_authordetail"."author_id" FROM "hello_authordetail" WHERE "hello_authordetail"."author_id" = 4; args=(4,)
In [20]: print(authordetail.sex)
False
In [21]: authordetail.sex = True
In [22]: print(authordetail.sex)
True
In [23]: authordetail.save()
(0.000) BEGIN; args=None
(0.001) UPDATE "hello_authordetail" SET "sex" = 1, "email" = 'landun@landun.com', "address" = 'www.landun.com', "birthday" = '2017-01-19', "author_id" = 4 WHERE "hello_authordetail"."id" = 5; args=(True, 'landun@landun.com', 'www.landun.com', '2017-01-19', 4, 5)
>>>
save的方法修改關聯表的數據
- upadte方法更新數據:先使用filter過濾,再用update更新:
In [26]: Publisher.objects.filter(id=4)
Out[26]: (0.001) SELECT "hello_publisher"."id", "hello_publisher"."name", "hello_publisher"."address", "hello_publisher"."city", "hello_publisher"."state_province", "hello_publisher"."country", "hello_publisher"."website" FROM "hello_publisher" WHERE "hello_publisher"."id" = 4 LIMIT 21; args=(4,)
[<Publisher: 哈爾濱出版社>]
In [27]: Publisher.objects.filter(id=4).update(name="麻省理工出版社")
(0.000) BEGIN; args=None
(0.001) UPDATE "hello_publisher" SET "name" = '麻省理工出版社' WHERE "hello_publisher"."id" = 4; args=('麻省理工出版社', 4)
Out[27]: 1
In [28]: print(Publisher.objects.filter(id=4))
(0.000) SELECT "hello_publisher"."id", "hello_publisher"."name", "hello_publisher"."address", "hello_publisher"."city", "hello_publisher"."state_province", "hello_publisher"."country", "hello_publisher"."website" FROM "hello_publisher" WHERE "hello_publisher"."id" = 4 LIMIT 21; args=(4,)
[<Publisher: 麻省理工出版社>]
update方法更新
2 QuerySet 對象的API
方法 | 說明 |
---|---|
get | 返回值是一個modules,僅返回一條數據;如果為空值,會拋出DoesNotExist異常 |
filter | 返回值是一個QuerySet類型的對象 |
all | |
order_by | |
distinct | |
values | 返回的是一個字典 |
values_list | 返回的是一個元組 |
count |
3 關聯查詢
- 多對多關聯查詢(外聯結查詢)【雙下劃線】
In [31]: Book.objects.filter(title="第一本《Python web 開發》").values('authors')
Out[31]: (0.000) SELECT "hello_book_authors"."author_id" FROM "hello_book" LEFT OUTER JOIN "hello_book_authors" ON ("hello_book"."id" = "hello_book_authors"."book_id") WHERE "hello_book"."title" = '第一本《Python web 開發》' LIMIT 21; args=('第一本《Python web 開發》',)
[{'authors': 1}]
In [32]: Book.objects.filter(title="第一本《Python web 開發》").values('authors__name')
Out[32]: (0.000) SELECT "hello_author"."name" FROM "hello_book" LEFT OUTER JOIN "hello_book_authors" ON ("hello_book"."id" = "hello_book_authors"."book_id") LEFT OUTER JOIN "hello_author" ON ("hello_book_authors"."author_id" = "hello_author"."id") WHERE "hello_book"."title" = '第一本《Python web 開發》' LIMIT 21; args=('第一本《Python web 開發》',)
[{'authors__name': '藍天'}]
多對多關聯查詢(外聯結查詢)
- 多對多關聯查詢(內鏈接的查詢) 【雙下劃線】
In [33]: Book.objects.filter(authors__name="藍天")
Out[33]: (0.118) SELECT "hello_book"."id", "hello_book"."title", "hello_book"."publisher_id", "hello_book"."publication_date", "hello_book"."price" FROM "hello_book" INNER JOIN "hello_book_authors" ON ("hello_book"."id" = "hello_book_authors"."book_id") INNER JOIN "hello_author" ON ("hello_book_authors"."author_id" = "hello_author"."id") WHERE "hello_author"."name" = '藍天' LIMIT 21; args=('藍天',)
[<Book: 第一本《Python web 開發》>, <Book: 第四本《BootStrap 框架》>, <Book: 第五本《Django 框架》>]
>>>
多對多關聯查詢(內鏈接的查詢)
- 外鍵關聯查詢【雙下劃線】
>>> AuthorDetail.objects.values('sex','email','address','birthday','author')
(0.001) SELECT `hello_authordetail`.`sex`, `hello_authordetail`.`email`, `hello_authordetail`.`address`, `hello_authordetail`.`birthday`, `hello_authordetail`.`author_id` FROM `hello_authordetail` LIMIT 21; args=()
[{'address': 'www.baidu.com', 'author': 1, 'sex': True, 'birthday': datetime.date(2017, 1, 19), 'email': 'admin@admin.com'}]
>>> AuthorDetail.objects.values('sex','email','address','birthday','author__name')
(0.002) SELECT `hello_authordetail`.`sex`, `hello_authordetail`.`email`, `hello_authordetail`.`address`, `hello_authordetail`.`birthday`, `hello_author`.`name` FROM `hello_authordetail` INNER JOIN `hello_author` ON (`hello_authordetail`.`author_id` = `hello_author`.`id`) LIMIT 21; args=()
[{'address': 'www.baidu.com', 'author__name': '張三2', 'sex': True, 'birthday': datetime.date(2017, 1, 19), 'email': 'admin@admin.com'}]
>>>
Paste_Image.png
- 主鍵類訪問外鍵類【_set】,使用的是get的方法
主鍵類訪問外鍵類
In [39]: pub = Publisher.objects.get(name="廣東人民出版社")
(0.000) SELECT "hello_publisher"."id", "hello_publisher"."name", "hello_publisher"."address", "hello_publisher"."city", "hello_publisher"."state_province", "hello_publisher"."country", "hello_publisher"."website" FROM "hello_publisher" WHERE "hello_publisher"."name" = '廣東人民出版社'; args=('廣東人民出版社',)
In [40]: pub.book_set.all()
Out[40]: (0.000) SELECT "hello_book"."id", "hello_book"."title", "hello_book"."publisher_id", "hello_book"."publication_date", "hello_book"."price" FROM "hello_book" WHERE "hello_book"."publisher_id" = 2 LIMIT 21; args=(2,)
[<Book: 第二本《Mysql 高級教程》>, <Book: 第十一本《Tronado 框架》>, <Book: 第十二本《廖雪峰 Python教程》>]
主鍵類訪問外鍵類【成功】
外鍵類訪問主鍵類
In [43]: book = Book.objects.get(title="第十二本《廖雪峰 Python教程》")
(0.000) SELECT "hello_book"."id", "hello_book"."title", "hello_book"."publisher_id", "hello_book"."publication_date", "hello_book"."price" FROM "hello_book" WHERE "hello_book"."title" = '第十二本《廖雪峰 Python教程》'; args=('第十二本《廖雪峰 Python教程》',)
In [44]: book.publisher_set.all()
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-44-7e20a9b508c8> in <module>()
----> 1 book.publisher_set.all()
AttributeError: 'Book' object has no attribute 'publisher_set'
外鍵類訪問主鍵類【失敗】
4 聚集查詢和分組查詢
4.0需要導入的庫文件
In [1]: from hello.models import *
In [2]: from django.db.models import *
4.1 Count
# 統計名為“廣東人民出版社”的出版商的數目
In [3]: Publisher.objects.filter(name="廣東人民出版社").aggregate(mycount = Count('name'))
(0.002) SELECT COUNT("hello_publisher"."name") AS "mycount" FROM "hello_publisher" WHERE "hello_publisher"."name" = '廣東人民出版社'; args=('廣東人民出版社',)
Out[3]: {'mycount': 1}
4.2 Sum
# 統計姓名為“藍天”的作者出書的總價
In [6]: Book.objects.filter(authors__name="藍天").aggregate(Sum('price'))
(0.001) SELECT CAST(SUM("hello_book"."price") AS NUMERIC) AS "price__sum" FROM "hello_book" INNER JOIN "hello_book_authors" ON ("hello_book"."id" = "hello_book_authors"."book_id") INNER JOIN "hello_author" ON ("hello_book_authors"."author_id" = "hello_author"."id") WHERE "hello_author"."name" = '藍天'; args=('藍天',)
Out[6]: {'price__sum': Decimal('148.00')}
Sum
4.3 values
# 統計每個作者出書的總價
In [7]: Book.objects.values('authors__name').annotate(Sum('price'))
Out[7]: (0.054) SELECT "hello_author"."name", CAST(SUM("hello_book"."price") AS NUMERIC) AS "price__sum" FROM "hello_book" LEFT OUTER JOIN "hello_book_authors" ON ("hello_book"."id" = "hello_book_authors"."book_id") LEFT OUTER JOIN "hello_author" ON ("hello_book_authors"."author_id" = "hello_author"."id") GROUP BY "hello_author"."name" LIMIT 21; args=()
[{'price__sum': Decimal('392.00'), 'authors__name': None}, {'price__sum': Decimal('10.00'), 'authors__name': '藍云'}, {'price__sum': Decimal('148.00'), 'authors__name': '藍天'}, {'price__sum': Decimal('153.00'), 'authors__name': '藍海'}]
values
4.4 Min
# 找出每個出版社里面價格最低的書
In [8]: Book.objects.values('publisher__name').annotate(Min('price'))
Out[8]: (0.000) SELECT "hello_publisher"."name", CAST(MIN("hello_book"."price") AS NUMERIC) AS "price__min" FROM "hello_book" INNER JOIN "hello_publisher" ON ("hello_book"."publisher_id" = "hello_publisher"."id") GROUP BY "hello_publisher"."name" LIMIT 21; args=()
[{'price__min': Decimal('10.00'), 'publisher__name': '\t廣東高等教育出版社'}, {'price__min': Decimal('85.00'), 'publisher__name': '人民教育出版社'}, {'price__min': Decimal('31.00'), 'publisher__name': '廣東人民出版社'}, {'price__min': Decimal('28.00'), 'publisher__name': '機械工業出版社'}, {'price__min': Decimal('92.00'), 'publisher__name': '清華大學出版社'}, {'price__min': Decimal('24.00'), 'publisher__name': '電子工業出版社'}, {'price__min': Decimal('87.00'), 'publisher__name': '麻省理工出版社'}]
Min
5 使用原生的SQL查詢
5.1 extra【QuerySet】對象
結果集修改器,一種提供額外查詢參數的機制,結果是一個【QuerySet】對象
In [7]: type(Book.objects.extra(select={'count':'select count(*) from hello_book'}))
Out[7]: django.db.models.query.QuerySet
# 查詢廣東人民出版社價格大于50的書
In [2]: Book.objects.filter(publisher__name="廣東人民出版社").extra(where=["price > 50"])
Out[2]: (0.001) SELECT "hello_book"."id", "hello_book"."title", "hello_book"."publisher_id", "hello_book"."publication_date", "hello_book"."price" FROM "hello_book" INNER JOIN "hello_publisher" ON ("hello_book"."publisher_id" = "hello_publisher"."id") WHERE ("hello_publisher"."name" = '廣東人民出版社' AND (price > 50)) LIMIT 21; args=('廣東人民出版社',)
[<Book: 第二本《Mysql 高級教程》>, <Book: 第十二本《廖雪峰 Python教程》>]
extra擴展查詢條件
# 查詢廣東人民出版社價格大于50的書
In [3]: Book.objects.filter(publisher__name='廣東人民出版社', price__gt=50)
Out[3]: (0.001) SELECT "hello_book"."id", "hello_book"."title", "hello_book"."publisher_id", "hello_book"."publication_date", "hello_book"."price" FROM "hello_book" INNER JOIN "hello_publisher" ON ("hello_book"."publisher_id" = "hello_publisher"."id") WHERE ("hello_publisher"."name" = '廣東人民出版社' AND "hello_book"."price" > '50') LIMIT 21; args=('廣東人民出版社', Decimal('50'))
[<Book: 第二本《Mysql 高級教程》>, <Book: 第十二本《廖雪峰 Python教程》>]
filter的方法實現條件查詢
# 匯總書籍表中的書
In [4]: Book.objects.extra(select={'count':'select count(*) from hello_book'})
Out[4]: (0.000) SELECT (select count(*) from hello_book) AS "count", "hello_book"."id", "hello_book"."title", "hello_book"."publisher_id", "hello_book"."publication_date", "hello_book"."price" FROM "hello_book" LIMIT 21; args=()
[<Book: 第一本《Python web 開發》>, <Book: 第二本《Mysql 高級教程》>, <Book: 第三本《HTML與CSS 高級編程》>, <Book: 第四本《BootStrap 框架》>, <Book: 第五本《Django 框架》>, <Book: 第六本《簡明Python教程》>, <Book: 第七本《Python web 開發》>, <Book: 第八本《Mysql 底層原理》>, <Book: 第九本《HTML與CSS 基礎教程》>, <Book: 第十本《Flask 框架》>, <Book: 第十一本《Tronado 框架》>, <Book: 第十二本《廖雪峰 Python教程》>]
extra擴展查詢語句
5.2 raw【RawQuerySet】對象
執行原始sql并返回模型實例,最適合用于查詢,結果是一個【QuerySet】對象
注意:RawQuerySet也是惰性的,只有在使用的時候才會被執行,特別是insert的時候要注意。
In [9]: type(Book.objects.raw('select * from hello_book'))
Out[9]: django.db.models.query.RawQuerySet
In [14]: for item in Book.objects.raw('select * from hello_book'):
...: print(item)
...:
(0.000) select * from hello_book; args=()
第一本《Python web 開發》
第二本《Mysql 高級教程》
第三本《HTML與CSS 高級編程》
第四本《BootStrap 框架》
第五本《Django 框架》
第六本《簡明Python教程》
第七本《Python web 開發》
第八本《Mysql 底層原理》
第九本《HTML與CSS 基礎教程》
第十本《Flask 框架》
第十一本《Tronado 框架》
第十二本《廖雪峰 Python教程》
第七本《Python web 開發》
raw方法查詢數據
5.3 直接執行自定義SQL
(這種方式完全不依賴model,前面兩種方式還是要依賴于model),適合增刪改
In [39]: from django.db import connection
In [40]: cursor = connection.cursor() #獲得一個游標(cursor)對象
In [41]: cursor.execute("insert into hello_author(name) values('藍盾')")
(0.272) insert into hello_author(name) values('藍盾'); args=None
Out[41]: <django.db.backends.sqlite3.base.SQLiteCursorWrapper at 0x234c355e8b8>
In [42]: cursor.execute("update hello_author set name = '藍網' where name='藍盾'")
(0.270) update hello_author set name = '藍網' where name='藍盾'; args=None
Out[42]: <django.db.backends.sqlite3.base.SQLiteCursorWrapper at 0x234c355e8b8>
In [43]: cursor.execute("delete from hello_author where name='藍網'")
(0.247) delete from hello_author where name='藍網'; args=None
Out[43]: <django.db.backends.sqlite3.base.SQLiteCursorWrapper at 0x234c355e8b8>
In [44]: cursor.execute('select * from hello_author')
(0.000) select * from hello_author; args=None
Out[44]: <django.db.backends.sqlite3.base.SQLiteCursorWrapper at 0x234c355e8b8>
In [45]: print(cursor.fetchone()) #執行結果第一條輸出
(1, '藍天')
In [46]: print(cursor.fetchall()) # 所有執行結果輸出,由于第一條已經輸出,所以游標從第二條開始
[(2, '藍海'), (3, '藍云'), (4, '藍視')
直接執行自定義SQL