Datawhale Django后端开发入门 TASK03 QuerySet和Instance、APIVIew

一、QuerySet

QuerySet 是 Django 中的一个查询集合,它是由 Model.objects 方法返回的,并且可以用于生成数据库中所有满足一定条件的对象的列表。

QuerySet 在 Django 中表示从数据库中获取的对象集合,它是一个可迭代的、类似列表的对象集合。主要特点包括:- 从 Model.objects 获得,表示数据库中所有该 Model 的对象集合。

- 可以添加过滤条件来限制查询结果,如 .filter()、`.exclude()`、`.order_by()` 等。

- 惰性执行,创建 QuerySet 不会立即执行查询,只有在需要求值时才查询数据库。- 可遍历,可以用在 for 循环中进行迭代。- 可切片,使用索引切片来获取一个子集。

- 支持链式调用过滤方法,每个过滤调用返回一个新的 QuerySet。

- 可以获取单个元素,如 .get() 返回单个匹配的对象。

- 支持转换为其他对象列表,如 .values()

- 可以转为字符串执行原始 SQL 查询。所以 QuerySet 是从数据库中获取模型对象数据的一个强大而灵活的接口。正确使用可以最大限度减少数据库查询,提高效率。每个 QuerySet 包含多个 Model 实例(Instance),表示满足查询条件的所有对象实例。

1.filter()方法接收的参数有:- 字段名,比如:.filter(name='John')
- 查询表达式,比如: .filter(age__gt=18)
- Q对象,用于复杂查询,比如:

from django.db.models import Qqueryset.filter(Q(age__gt=18) & Q(name='John'))

关键字参数,比如:.filter(name='John', age__gt=18)filter()会基于给定的参数生成一个新的过滤后的QuerySet。例如:

Article.objects.filter(published=True) # 已发布文章Article.objects.filter(title__contains='Django') # 标题包含Django的文章Article.objects.filter(Q(title__contains='Django') | Q(title__contains='Python'))
# 标题包含Django或Python的文章

重要的是,filter()并不会立即执行查询,只是返回一个新的QuerySet,真正的数据库查询会在需要求值的时候发生。我们可以多次调用filter()来链式过滤,每个filter()调用会基于前一个QuerySet然后返回一个新的QuerySet。

2.get()

get()方法与filter()有些类似,主要区别在于:

(1. get()用来获取单个对象,而filter()获取一个对象集合(queryset)。

(2. get()只能返回一个满足条件的对象实例,如果不存在会引发模型类的DoesNotExist异常。

(3. get()无法链接调用,只能获取单个对象。例如:

# 获取id=1的文章
article = Article.objects.get(id=1) # 查询标题包含'Python'的文章,如果不存在会报错
article = Article.objects.get(title__contains='Python')# filter()返回满足条件的所有文章
articles = Article.objects.filter(title__contains='Python')

所以get()主要用于根据过滤条件获取单个对象,这对于获取某个具体模型实例很有用,但需要注意如果不存在会引发异常。而filter()用于获取多个满足条件的对象,这对获取一个QuerySet集合并对其进一步处理很有用。需要根据具体场景选择使用get()还是filter()。

3.all()

Django中的`Model.objects.all()`方法返回该模型的全部对象集合。它相当于没有任何过滤条件的`filter()`查询:

Article.objects.all()
# 等同于
Article.objects.filter()

all()返回的是一个包含该模型所有对象的QuerySet。我们可以在`all()`的基础上进一步链式过滤:

Article.objects.all().filter(published=True) 

all()对于获取某个模型的全部数据很有用。当然,如果数据量很大,我们可能需要限制返回的数据条数,以提高性能。另外,all()每次都会查询数据库。如果需要多次使用全部数据集,可以考虑使用缓存或预取相关对象:prefetch_related()。所以在合适的时候使用`all()`可以方便地获取模型的全部实例,但需要注意数据量大小和重复查询的问题。

4.delete()

delete()方法将删除QuerySet中的所有对象,并返回删除的对象数量。

  @action(detail=False, methods=['get','post'])def delete_example(self, request):name = request.data.get('name')# 删除名称为 'name' 的商品categories_to_delete = GoodsCategory.objects.filter(name=name)# 使用delete()方法删除对象deleted_count= categories_to_delete.delete()print(f"Deleted {deleted_count} categories.")      

主要流程是:1. 通过filter()筛选出需要删除的对象集合2. 在这个QuerySet上调用delete()方法实现删除3. delete()方法会删除QuerySet中的所有对象,并返回删除的对象数量所以delete()为批量删除QuerySet中的对象提供了很好的便利。注意delete()会立即执行删除操作,不像filter()那样是延迟执行。另外,delete()默认不会触发模型的delete()方法,如果需要调用可以设置:

categories_to_delete.delete(keep_parents=False)

这样会为每个对象调用delete()方法。delete()方法非常适合批量删除不需要的对象,可以用来定期清理数据库。但需要注意确保筛选条件正确,避免误删除。

5.update()

update() 方法将对QuerySet进行筛选,获取需要更新的对象集合,然后执行数据库更新操作。基本语法如下:

queryset.update(字段1=值1, 字段2=值2...)

这将设置指定的字段到相应的值。例如:

Article.objects.filter(published=True).update(status='p') 
# 将已发布文章的状态都设为'p'Article.objects.filter(id__in=[1,2,3]).update(views=F('views') + 1)
# 对id为1,2,3的文章浏览量增1

update()默认只会更新指定的字段。需要注意,update()同样会立即执行更新,并返回更新的行数。update()提供了一个非常高效的批量更新对象方法,可以避免大量的单个对象更新开销。但同样需要确保更新条件的准确性。

6.create()

create() 方法是 save() 方法的快捷方式,用于创建并保存一个新的对象。

@action(detail=False, methods=['get','post'])def create_example(self, request):name = request.data.get('name')# 使用create()方法创建新的商品分类对象created_category = GoodsCategory.objects.create(name)print("Created category:", created_category) 

主要的用法是:

GoodsCategory.objects.create(name='名称', field1='值1',...)

这将实例化GoodsCategory,为其设置指定的字段值,然后直接保存到数据库中。与下面的用法等价:

category = GoodsCategory(name='名称', field1='值1',...) 
category.save()

所以create()方法对于快速创建对象非常方便,尤其是在数据初始化或者测试中可以减少代码量。需要注意:- create()参数必须提供对象必填字段的值
- create()会自动保存对象,无需再调用save()
- 创建成功后会返回新创建的对象实例综上,create()是save()方法的一个非常好用的封装,可以简化对象创建的代码。

7.count()

Django QuerySet 中的 count() 方法可以用来返回满足指定查询条件的对象的总数。count() 方法会执行查询,获取匹配查询(filters)的对象数目。使用方式:

Article.objects.filter(published=True).count() # 返回已发布文章数Article.objects.filter(title__contains='Django').count() # 返回标题包含'Django'的文章数

Article.objects.filter(published=True).count() # 返回已发布文章数 Article.objects.filter(title__contains='Django').count() # 返回标题包含'Django'的文章数

count()会执行查询数据库的COUNT操作,性能上比提取所有对象再计算列表长度要更高效,尤其是数据量很大的时候。我们可以像链式调用filter()一样,链式调用count()来获取不同条件下的数量:

Article.objects.filter(published=True).filter(views__gt=10).count() 
# 返回已发布且浏览量大于10的文章数。

需要注意,使用count()之后再继续链式过滤就不会生效了。所以count()为我们提供了一个简单直观的方式来获取查询集大小。可以用来判断是否有匹配的对象,或者计算比较不同查询的结果数目。

8.order_by()

Django QuerySet 中order_by()方法用于对返回的对象进行排序。order_by()的常见用法:

# 按发布日期升序排序
Article.objects.order_by('publish_date') # 按浏览量降序排序 
Article.objects.order_by('-views')# 先按发布日期降序,再按标题升序
Article.objects.order_by('-publish_date', 'title')

默认order_by()是按升序排列的,如果需要降序,可以在参数字段名前加一个负号-。可以传递多个字段名来先后进行排序,如上面的例子。order_by()通常用在需要排序的查询中,比如获取最新文章:

latest_articles = Article.objects.order_by('-publish_date')[:10] 

需要注意order_by()通常应该放在链式查询的最后,因为它会改变查询结果的顺序。order_by()非常实用,可以帮助我们按任意字段排序查询集,灵活地获取需要的数据。

9.values()

在Django中,values()方法可以用来获取QuerySet中的对象的指定字段的值,返回一个ValueQueryset,里面是以字典形式包含指定字段值的对象。那么

Map.objects.all().values().first()

的作用就是:

(1. Map.objects.all() 返回Map模型的全部对象的QuerySet

(2. 在这个QuerySet上调用`.values()`,不指定任何字段,那么会返回包含每个对象的所有字段及值的字典。

(3. 最后调用.first()返回第一个对象的字段字典。例如,如果Map模型有字段id, name, address,那么它类似于:

{'id': 1,'name': 'John','address': '123 Main St' 
}

如果我们只需要名称和地址:

Map.objects.all().values('name', 'address').first()

那么得到的是:

{'name': 'John','address': '123 Main St'
}

这可以避免提取整个对象然后访问字段,提高效率。所以values()方法非常适合只需要获取对象某些字段的值而不需要模型对象实例的时候使用。

 二、Instance

创建一个对象:Obj = Model(attr1=val1, attr2=val2),Obj.save()
更新一个对象:Obj = Model.objects.get(id=xxx),Obj.attr1 = val1,Obj.save()
删除一个对象:Obj = Model.objects.get(id=xxx),Obj.delete()

Django模型实例(Instance)表示的是数据库中一个模型对象的一行记录。它可以完成如下操作:

1. 创建对象实例可以通过Model类直接创建:

obj = Model(attr1=val1, attr2=val2)
obj.save()

或者使用objects管理器的create()方法:

obj = Model.objects.create(attr1=val1, ...)

2. 更新对象实例先获取实例,修改字段后保存:

obj = Model.objects.get(id=1) 
obj.attr1 = new_value
obj.save()

3. 删除对象实例获取实例后调用delete():

obj = Model.objects.get(id=1)
obj.delete()

所以Django模型实例表示单个对象,主要用于对象的CRUD操作。它和QuerySet的区别在于是一个对象 VS 一组对象。

QuerySet 适用于需要查找多个对象或进行聚合操作的场景,而 Instance 适用于单独对象的创建、修改和删除操作。

三、APIView(在 view.py 中)

 

 

APIview 是 Django REST Framework 提供的一个视图类。它和 Django 中的 view 类有些相似,但是又有一些不同之处。APIview 可以处理基于 HTTP 协议的请求,并返回基于内容协商的响应,它旨在提供一个易于使用且灵活的方式来构建 API 视图。

- APIView继承自Django的View类,提供了许多处理HTTP请求的方法,比如get、post等。

- APIView实现了内容协商,可以根据请求头中的Accept信息自动返回JSON或其他格式。

- APIView具有请求解析器,可以解析请求的数据,并将请求数据绑定到请求对象上。- APIView可以轻松地构建基于类的视图逻辑,通过继承和组合来重用通用逻辑。

- APIView支持基于函数的视图行为,可以使用@action装饰器来实现。

- APIView比Django的View类更偏向于构建Web API。它提供了对请求和响应的更多控制能力。

- APIView需要与序列化器Serializer配合使用,来序列化复杂数据。

总结起来,APIView是一个专门用来构建Web API的类,它建立在Django的通用View组件之上,提供了对requests和responses的控制,内容协商等功能,以及对Serializer的集成,可以更便捷地构建灵活的API。 

这里是一个使用APIView的代码示例:(可与项目给出的示例做对比补充)

from rest_framework.views import APIView
from rest_framework.response import Responseclass HelloView(APIView):def get(self, request):content = {'message': 'Hello, World!'}return Response(content)def post(self, request):name = request.data.get('name')content = {'message': 'Hello, {}!'.format(name)}return Response(content)

这个示例中定义了一个简单的HelloView,继承自APIView。

- get() 方法处理GET请求,返回一个字典作为响应数据。

- post() 方法处理POST请求,从请求数据中获取name参数,返回个性化的问候信息。

- APIView会自动根据请求方法调用对应的get或post方法。

- 返回Response对象,APIView会处理内容协商,转换数据格式。这样,就可以快速构建一个支持GET/POST的API端点了。我们还可以利用APIView提供的其他功能,比如解析器、身份验证等来构建更强大的API。APIView作为Django REST framework的基础,提供了简洁而不失灵活性的API视图构建方式。

# 面向对象编程
from django.shortcuts import render
from rest_framework.decorators import api_view
from .models import *
from rest_framework.response import Response
from rest_framework.views import APIView
#### APIViewclass GetGoods(APIView):def get(self, request):data = Goods.objects.all()serializer = GoodsSerializer(instance=data, many=True)print(serializer.data)return Response(serializer.data)def post(self, request):# 从请求数据中提取字段request_data = {"category": request.data.get("Goodscategory"),"number": request.data.get("number"),"name": request.data.get("name"),"barcode": request.data.get("barcode"),"spec": request.data.get("spec"),"shelf_life_days": request.data.get("shelf_life_days"),"purchase_price": request.data.get("purchase_price"),"retail_price": request.data.get("retail_price"),"remark": request.data.get("remark"),}# 使用 create() 方法创建新的商品对象new_goods = Goods.objects.create(**request_data)# 对创建的对象进行序列化,并作为响应返回serializer = GoodsSerializer(instance=new_goods)return Response(serializer.data)# 面向对象编程class FilterGoodsCategoryAPI(APIView):# request 表示当前的请求对象# self 表示当前实例对象def get(self, request, format=None):print(request.method)return Response('ok')def post(self, request, format=None):print(request.method)return Response('ok')def put(self, request, format=None):print(request.method)return Response('ok')

实现了一个简单的商品信息获取接口。主要逻辑是:

1. 从Goods模型中获取所有商品对象数据

2. 用GoodsSerializer序列化器对商品数据进行序列化

3. 将序列化后的数据通过Response返回这样就实现了一个获取所有商品信息的API端点。

需要注意的是:

- APIView会自动根据请求方法调用对应的方法处理器,如这里的get()来处理GET请求。

- 数据需要序列化后才能作为JSON响应返回,这里使用rest_framework的Serializer完成。

- Response包含了内容协商、状态码等响应处理功能。

使用APIView的优点是:

- 继承APIView就直接拥有了请求调度、响应处理等功能- 可以通过面向对象的方式组织视图逻辑,扩展灵活- 结合Serializer可以快速实现序列化与响应总之,这是一个典型的使用APIView构建API的示例,利用其提供的封装与便利性来简化视图开发。

def post(self, request):# 从请求数据中提取字段request_data = {"category": request.data.get("Goodscategory"),"number": request.data.get("number"),"name": request.data.get("name"),"barcode": request.data.get("barcode"),"spec": request.data.get("spec"),"shelf_life_days": request.data.get("shelf_life_days"),"purchase_price": request.data.get("purchase_price"),"retail_price": request.data.get("retail_price"),"remark": request.data.get("remark"),}

这个post方法实现了从请求数据中提取需要的参数来创建商品的功能。主要逻辑:

1. 从request.data中获取前端传来的各个字段的数据

2. 将获取到的数据保存到一个字典request_data中

3. request_data中的key就是模型的字段名,value是从请求中获取到的值

4. 这样就可以直接用这个request_data字典来创建商品实例:

goods = Goods.objects.create(**request_data)

这种字典参数的解包语法可以直接把字典的值赋给模型的对应字段。

5. 最后可能需要返回创建好的商品数据给前端:

serializer = GoodsSerializer(goods)
return Response(serializer.data)

这样,我们就可以通过接受用户输入的数据来创建新的商品,并返回结果。这种从请求中提取参数,然后直接解包传递的方式可以简化创建对象的代码。配合DRF的Serializer来序列化和响应数据,可以快速构建出创建对象的API。

# 面向对象编程class FilterGoodsCategoryAPI(APIView):# request 表示当前的请求对象# self 表示当前实例对象def get(self, request, format=None):print(request.method)return Response('ok')def post(self, request, format=None):print(request.method)return Response('ok')def put(self, request, format=None):print(request.method)return Response('ok')

实现了一个商品分类过滤的API视图,演示了APIView中如何根据不同的HTTP方法来处理不同的业务逻辑。

主要逻辑:

- 定义了FilterGoodsCategoryAPI类,继承APIView

- 分别实现了get(), post(), put()方法来处理不同的HTTP请求方法

- 在每个方法内部,打印了request.method,用于验证接收到的请求方法

- 然后直接返回字符串'ok'作为响应这样,当一个GET请求发送到这个视图的时候,会调用get()方法,并在终端打印输出“GET”。对于POST或PUT请求,也会分别调用对应的方法,并打印“POST”或“PUT”。APIView会自动根据请求方法将不同的请求分发到对应方法进行处理。我们可以在每个方法内实现真正的业务逻辑,比如获取分类、添加商品等。这种面向对象的类视图可以帮助我们更好地组织代码,利用APIView的请求分发来处理不同的请求与业务逻辑。

所以这是一个使用APIView的典型示例,演示了其根据请求方法调度到对应方法的功能。

未完待续

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/45373.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

自我管理篇--工作做完了,我能不能到点就下班

以上简历模板资源的排版可能不是最优,但工作经历可以借鉴 工作做完了,我能不能到点就下班? 答案:是,每个人都是自由的 ​ 工作完了,我能不能准点下班,背后真正的问题是:你有没有找到那件让你愿意…

Amazon CloudFront 部署小指南(六)- Lambda@Edge 基础与诊断

内容简介 本文适用于希望使用 Amazon CloudFront LambdaEdge 提升 Amazon CloudFront 边缘计算能力的用户,旨在帮助您更好的进行 CloudFront LambdaEdge 的开发、调试、测试、部署等工作。 首先我们会对 CloudFront LambdaEdge 做个简单的介绍,然后分七个…

kafka--kafka的基本概念-副本概念replica

三、kafka的基本概念-副本概念replica Broker 表示实际的物理机器节点 Broker1中的绿色P1表示主分片Broker2中的蓝色P1表示副本分片,其余类似,就是主从的概念,如果一个Broker挂掉了,还有其它的节点来保证数据的完整性 P可以看做分…

OpenCV实例(九)基于深度学习的运动目标检测(三)YOLOv3识别物体

基于深度学习的运动目标检测(三)YOLOv3识别物体 1.基于YOLOv3识别物体2.让不同类别物体的捕捉框颜色不同3.不用Matplotlib实现目标检测 目标检测,粗略地说就是输入图片/视频,经过处理后得到目标的位置信息(比如左上角和…

Android岗位技能实训室建设方案

一 、系统概述 Android岗位技能作为新一代信息技术的重点和促进信息消费的核心产业,已成为我国转变信息服务业的发展新热点:成为信息通信领域发展最快、市场潜力最大的业务领域。互联网尤其是移动互联网,以其巨大的信息交换能力和快速渗透能力…

leetcode做题笔记92. 反转链表 II

给你单链表的头指针 head 和两个整数 left 和 right &#xff0c;其中 left < right 。请你反转从位置 left 到位置 right 的链表节点&#xff0c;返回 反转后的链表 。 示例 1&#xff1a; 思路一&#xff1a;头插法 struct ListNode *reverseBetween(struct ListNode *h…

河北人事档案管理系统

河北人事档案管理系统是一个集数字化管理、高效服务、安全可靠于一体的人事档案管理平台&#xff0c;可以集中管理机关事业单位人事档案、农村党员档案、参保职工档案、流动人才档案等&#xff0c;并实现高效、便捷的查阅和调阅服务。 河北人事档案管理系统的建设主要是为了更好…

成集云 | 电子签署集成腾讯云企业网盘 | 解决方案

源系统成集云目标系统 方案介绍 电子签署是通过电子方式完成合同、文件或其他文件的签署过程。相较于传统的纸质签署&#xff0c;电子签署具有更高效、更便捷、更安全的优势。 在电子签署过程中&#xff0c;使用电子签名技术来验证签署者的身份并确保签署文件的完整性。电子…

华为OD七日集训第1期 - 按算法分类,由易到难,循序渐进,玩转OD(文末送书)

目录 一、适合人群二、本期训练时间三、如何参加四、7日集训第一期 ~ 华为OD初体验五、精心挑选21道高频100分经典题目&#xff0c;作为入门。第1天、逻辑分析第2天、字符串处理第3天、数据结构第4天、双指针第5天、递归回溯第6天、二分查找第7天、贪心算法 && 二叉树 …

dirsearch目录扫描工具的使用

文章目录 工具下载及环境准备查看帮助信息进行目录扫描 官方介绍 &#xff1a;An advanced command-line tool designed to brute force directories and files in webservers, AKA web path scanner 一个高级命令行工具&#xff0c;用于暴力破解网络服务器中的目录和文件&…

C++中List的实现

前言 数据结构中&#xff0c;我们了解到了链表&#xff0c;但是我们使用时需要自己去实现链表才能用&#xff0c;但是C出现了list将这一切皆变为现。list可以看作是一个带头双向循环的链表结构&#xff0c;并且可以在任意的正确范围内进行增删查改数据的容器。list容器一样也是…

【JVM】运行时数据区——自问自答

Q:Java 运行时数据区解构&#xff0c;哪些数据线程独占&#xff0c;哪些是线程共享&#xff1f;每个区域会产生GC和异常吗&#xff1f; 运行时数据区&#xff1a; 1、PC寄存器 2、堆区 3、JVM栈 4、Native栈 5、方法区 其中&#xff0c;PC寄存器、Native栈、JVM栈是线程独占的…

如何在pycharm中指定GPU

如何在pycharm中指定GPU 作者:安静到无声 个人主页 目录 如何在pycharm中指定GPU打开编辑配置点击环境变量添加GPU配置信息推荐专栏在Pycharm运行程序的时候,有时候需要指定GPU,我们可以采用以下方式进行设置: 打开编辑配置 点击环境变量 添加GPU配置信息 添加名称:CU…

geacon_pro配合catcs4.5上线Mac、Linux

我的个人博客: xzajyjs.cn 一些链接 Try师傅的catcs4.5项目: https://github.com/TryGOTry/CobaltStrike_Cat_4.5&#xff0c;最新版解压密码见&#xff1a;https://www.nctry.com/2708.html geacon_pro: https://github.com/testxxxzzz/geacon_pro BeaconTool.jar: https:/…

【LLM评估篇】Ceval | rouge | MMLU等指标

note 一些大模型的评估模型&#xff1a;多轮&#xff1a;MTBench关注评估&#xff1a;agent bench长文本评估&#xff1a;longbench&#xff0c;longeval工具调用评估&#xff1a;toolbench安全评估&#xff1a;cvalue&#xff0c;safetyprompt等 文章目录 note常见评测benchm…

ubuntu20搭建环境使用的一下指令

1.更新源 sudo vim etc/apt/sources.listdeb http://mirrors.aliyun.com/ubuntu/ xenial main deb-src http://mirrors.aliyun.com/ubuntu/ xenial maindeb http://mirrors.aliyun.com/ubuntu/ xenial-updates main deb-src http://mirrors.aliyun.com/ubuntu/ xenial-updates…

Redis实现共享Session

Redis实现共享Session 分布式系统中&#xff0c;sessiong共享有很多的解决方案&#xff0c;其中托管到缓存中应该是最常用的方案之一。 1、引入依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM…

openGauss学习笔记-44 openGauss 高级数据管理-存储过程

文章目录 openGauss学习笔记-44 openGauss 高级数据管理-存储过程44.1 语法格式44.2 参数说明44.3 示例 openGauss学习笔记-44 openGauss 高级数据管理-存储过程 存储过程是能够完成特定功能的SQL语句集。用户可以进行反复调用&#xff0c;从而减少SQL语句的重复编写数量&…

SpringBoot 学习(03): 弱语言的注解和SpringBoot注解的异同

弱语言代表&#xff1a;Hyperf&#xff0c;一个基于 PHP Swoole 扩展的常驻内存框架 注解概念的举例说明&#xff1b; 说白了就是&#xff0c;你当领导&#xff0c;破烂事让秘书帮你去安排&#xff0c;你只需要批注一下&#xff0c;例如下周要举办一场活动&#xff0c;秘书将方…

sql server安装报错 合成活动模板库(ATL) 失败

错误 “合成活动模板库(ATL) 规则失败“ 解决办法&#xff1a; 进入SQL Server 2008R2安装包目录找到文件&#xff1a;sqlsupport_msi&#xff0c;安装此文件之后&#xff0c;再安装SQL Server&#xff0c;便可解决该问题。C:\SQL Server 2008R2\new\SQL Server 2008R2\2052_CH…