0%

du命令用于显示目录或文件的大小。du会显示指定的目录或文件所占用的磁盘空间。

语法
du [-abcDhHklmsSx][-L <符号连接>][-X <文件>][–block-size][–exclude=<目录或文件>][–max-depth=<目录层数>][–help][–version][目录或文件]
参数说明:

-a或-all 显示目录中个别文件的大小。
-b或-bytes 显示目录或文件大小时,以byte为单位。
-c或--total 除了显示个别目录或文件的大小外,同时也显示所有目录或文件的总和。
-D或--dereference-args 显示指定符号连接的源文件大小。
-h或--human-readable 以K,M,G为单位,提高信息的可读性。
-H或--si 与-h参数相同,但是K,M,G是以1000为换算单位。
-k或--kilobytes 以1024 bytes为单位。
-l或--count-links 重复计算硬件连接的文件。
-L<符号连接>或--dereference<符号连接> 显示选项中所指定符号连接的源文件大小。
-m或--megabytes 以1MB为单位。
-s或--summarize 仅显示总计。
-S或--separate-dirs 显示个别目录的大小时,并不含其子目录的大小。
-x或--one-file-xystem 以一开始处理时的文件系统为准,若遇上其它不同的文件系统目录则略过。
-X<文件>或--exclude-from=<文件> 在<文件>指定目录或文件。
--exclude=<目录或文件> 略过指定的目录或文件。
--max-depth=<目录层数> 超过指定层数的目录后,予以忽略。
--help 显示帮助。
--version 显示版本信息。

实例
显示目录或者文件所占空间:

du

608     ./test6
308     ./test4
4       ./scf/lib
4       ./scf/service/deploy/product
4       ./scf/service/deploy/info
12      ./scf/service/deploy
16      ./scf/service
4       ./scf/doc
4       ./scf/bin
32      ./scf
8       ./test3
1288    .

只显示当前目录下面的子目录的目录大小和当前目录的总的大小,最下面的1288为当前目录的总大小

显示指定文件所占空间

du log2012.log

300     log2012.log

方便阅读的格式显示test目录所占空间情况:

du -h test

608K    test/test6
308K    test/test4
4.0K    test/scf/lib
4.0K    test/scf/service/deploy/product
4.0K    test/scf/service/deploy/info
12K     test/scf/service/deploy
16K     test/scf/service
4.0K    test/scf/doc
4.0K    test/scf/bin
32K     test/scf
8.0K    test/test3
1.3M    test

react-native-redux入门 & 使用Visual Studio Code和typescript 开发调试React Native项目 之后,这次我们继续 React Native Typescript 系列

项目初始化的细节就不一一叙述的,感兴趣的同学可以看下上面两篇博客,我把最终代码放到了 我的github仓库上,里面有每个步骤的修改的代码记录。

原来的样子

首先我们修改我们的src/index.tsx 实现一个简单的计数器 代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import React, { Component } from "react";
import {
StyleSheet,
Text,
View,
Button,
Platform
} from "react-native";
interface Props {
}
interface State {
count:number;
}
const instructions = Platform.select({
ios: 'Press Cmd+R to reload,\n' + 'Cmd+D or shake for dev menu',
android:
'Double tap R on your keyboard to reload,\n' +
'Shake or press menu button for dev menu',
});
export default class App extends Component<Props, State> {
constructor(props:Props)
{
super(props);
this.state={count:0};

}
add = ()=>{

this.setState({count:this.state.count+1})
};
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>Welcome to React Native&typescript!</Text>
<Text style={styles.instructions}>To get started, edit src/App.js</Text>
<Text style={styles.instructions}>{instructions}</Text>
<Text style={styles.instructions}>{this.state.count}</Text>
<Button onPress={this.add} title="add" ></Button>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
});

开始redux

接下来我们按照Redux管理React数据流实现代码
在开始之前我们学习下Redux
react-native-typescript-redux-201877184819
在图中,使用Redux管理React数据流的过程如图所示,Store作为唯一的state树,管理所有组件的state。组件所有的行为通过Actions来触发,然后Action更新Store中的state,Store根据state的变化同步更新React视图组件。
需要注意的是:
在主入口文件index.tsx中,通过Provider标签把Store和视图绑定:

<Provider store={store}>
    //项目代码
</Provider>

actions

指全局发布的动作指令,主要就是定义所有事件行为的

首先声明定义 actionsTypes
actionsTypes.ts

1
export const ADD ="ADD";

新建actions.ts

1
2
3
4
5
6
import {ADD} from './actionsTypes';

const add=()=>({type:ADD})
export {
add
}

reducers

Store是如何具体管理State呢?实际上是通过Reducers根据不同的Action.type来更新不同的state,即(previousState,action) => newState。最后利用Redux提供的函数combineReducers将所有的Reducer进行合并,更新整个State树

会用到的state类型
statesTypes.ts

1
2
3
export class CounterState{
count:number
}

新建reducers.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import { combineReducers } from 'redux';
import {ADD} from './actionsTypes';
import {CounterState} from './statesTypes';

const defaultState={
count:0
} as CounterState;
function counter(state=defaultState,action:any){
switch (action.type) {
case ADD:
return {...state,count:state.count+1};
default:
return state;
}
}
export default combineReducers({
counter:counter
});

store

在 Redux 应用中,只允许有一个 store 对象,管理应用的 state.可以理解为一个存放APP内所有组件的state的仓库.
可以通过 combineReducers(reducers) 来实现对 state 管理的逻辑划分(多个 reducer)。

新建store.ts

1
2
3
4
5
import { createStore, applyMiddleware, compose } from 'redux';
import rootReducer from './reducers';

const store=createStore(rootReducer);
export default store;

Provider

Provider 本身并没有做很多事情,只是把 store放在 context 里罢了,本质上 Provider 就是给 connect 提供 store 用的。

新建index.tsx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import React, { Component } from 'react';
import { Provider } from 'react-redux';
import Home from './home';
import store from './store';

export default class App extends Component {
render() {
return (
<Provider store={store}>
<Home/>
</Provider>
);
}
}

Container

利用Container容器组件作为桥梁,将React组件和Redux管理的数据流联系起来。Container通过connect函数将Redux的state和action转化成展示组件即React组件所需的Props。

新建home.tsx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import React, { Component } from 'react';
import {
StyleSheet,
Text,
View,
Button,
Platform
} from 'react-native';
import { connect, DispatchProp } from 'react-redux';
import { add } from './actions';
import {CounterState} from './statesTypes';

interface State {
}
type Props=CounterState&DispatchProp
const instructions = Platform.select({
ios: 'Press Cmd+R to reload,\n' + 'Cmd+D or shake for dev menu',
android:
'Double tap R on your keyboard to reload,\n' +
'Shake or press menu button for dev menu',
});
class Home extends Component<Props, State> {
constructor(props:Props)
{
super(props);
}
_add = ()=>{

this.props.dispatch(add())
};
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>Welcome to React Native&typescript!</Text>
<Text style={styles.instructions}>To get started, edit src/App.js</Text>
<Text style={styles.instructions}>{instructions}</Text>
<Text style={styles.instructions}>{this.props.count}</Text>
<Button onPress={this._add} title="add" ></Button>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
});

const mapStateToProps = (state:any) => (
state.counter
)

export default connect(mapStateToProps)(Home);

最终代码在 https://github.com/YahuiWong/react-native-typescript/tree/114aefbd3fbb96f9c67db068b340b908ed54276d
可在线查看

上一篇博客我们用理论和代码实践介绍了 使用redux 发起action 在reducers里生成state 然后重新渲染组件

Redux 的核心理念是严格的单向数据流,只能通过 dispatch(action) 的方式修改 store,流程如下:

view ->  action -> reducer -> store

但是在业务复杂的以及和api数据对接的过程中肯定会遇到大量的异步操作。我们如何来解决这些场景呢?

redux中间件

什么是redux中间件

redux中间件
这里我们先从redux的中间件说起, 中间件,顾名思义:进行中间处理的物件。类似于面向对象编程的AOP编程思想(不了解AOP的可以忽略这句话)
简单的说:中间件可以控制在store dispatch action之前和之后的业务逻辑。也就是说 中间件实现了改写 store.dispatch 方法实现了action -> reducer的拦截的行为。
如果我们分别注册三个中间件: 中间件A 中间件B 中间件C
那么

中间件A -> 中间件B-> 中间件C-> 原始 dispatch -> 中间件C -> 中间件B -> 中间件A

和异步处理的关系

综上所述:中间件可以领过的改变 dispatch的时机,这样我们就可以很方便的处理异步场景了。
因此各种 redux异步处理中间件应运而生。比较知名的有redux-thunkredux-saga

redux-thunk

redux-thunk中间件可以让action创建函数先不返回一个action对象,而是返回一个函数,函数传递两个参数(dispatch,getState),在函数体内进行业务逻辑的封装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function add() {
return {
type: 'ADD',
}
}

function addIfOdd() {
return (dispatch, getState) => {
const currentValue = getState();
if (currentValue % 2 == 0) {
return false;
}
//分发一个任务
dispatch(add())
}
}

详细代码可以查看分支:https://github.com/YahuiWong/react-native-typescript/tree/redux-thunk

redux-saga

sages 采用 Generator 函数来 yield Effects(包含指令的文本对象)。Generator 函数的作用是可以暂停执行,再次执行的时候从上次暂停的地方继续执行。Effect 是一个简单的对象,该对象包含了一些给 middleware 解释执行的信息。你可以通过使用 effects API 如 fork,call,take,put,cancel 等来创建 Effect。( redux-saga API 参考)

如 yield call(fetch, ‘/products’) 即 yield 了下面的对象,call 创建了一条描述结果的信息,然后,redux-saga middleware 将确保执行这些指令并将指令的结果返回给 Generator:

1
2
3
4
5
6
// Effect -> 调用 fetch 函数并传递 `./products` 作为参数
{
type: CALL,
function: fetch,
args: ['./products']
}

与 redux-thunk 不同的是,在 redux-saga 中,UI 组件自身从来不会触发任务,它们总是会 dispatch 一个 action 来通知在 UI 中哪些地方发生了改变,而不需要对 action 进行修改。redux-saga 将异步任务进行了集中处理,且方便测试。

dispacth({ type: ‘FETCH_REQUEST’, url: /* … */} );
所有的东西都必须被封装在 sagas 中。sagas 包含3个部分,用于联合执行任务:

worker saga
做所有的工作,如调用 API,进行异步请求,并且获得返回结果
watcher saga
监听被 dispatch 的 actions,当接收到 action 或者知道其被触发时,调用 worker saga 执行任务
root saga
立即启动 sagas 的唯一入口

☀ 如何使用?
首先,我们得在文件入口中加入 saga 中间件,并且启动它,它会一直运行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//...
import { createStore, applyMiddleware} from 'redux';
import createSagaMiddleware from 'redux-saga';
import appReducer from './reducers';
import rootSaga from './saga';
//...

const sagaMiddleware = createSagaMiddleware()

const store=createStore(rootReducer,applyMiddleware(sagaMiddleware));

sagaMiddleware.run(rootSaga)

render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('app')
);

然后,就可以在 sagas 文件夹中集中写 saga 文件了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import {delay} from 'redux-saga';
import {put,takeEvery,all} from 'redux-saga/effects';
import {ADD} from './actionsTypes';
function* addSync(){
yield delay(1000);
yield put({type:ADD})
}
function* watchaddSync(){
yield takeEvery("addSync",addSync)
}

export default function* rootSaga(){
yield all([
watchaddSync()
])
}

在 redux-saga 中的基本概念就是:sagas 自身不真正执行副作用(如函数 call),但是会构造一个需要执行作用的描述。中间件会执行该副作用并把结果返回给 generator 函数。

对上述例子的说明:

(1)引入的 redux-saga/effects 都是纯函数,每个函数构造一个特殊的对象,其中包含着中间件需要执行的指令,如:call(fetchUrl, url) 返回一个类似于 {type: CALL, function: fetchUrl, args: [url]} 的对象。

(2)在 watcher saga watchFetchRequests中:

首先 yield take(‘FETCH_REQUEST’) 来告诉中间件我们正在等待一个类型为 FETCH_REQUEST 的 action,然后中间件会暂停执行 wacthFetchRequests generator 函数,直到 FETCH_REQUEST action 被 dispatch。一旦我们获得了匹配的 action,中间件就会恢复执行 generator 函数。

下一条指令 fork(fetchUrl, action.url) 告诉中间件去无阻塞调用一个新的 fetchUrl 任务,action.url 作为 fetchUrl 函数的参数传递。中间件会触发 fetchUrl generator 并且不会阻塞 watchFetchRequests。当fetchUrl 开始执行的时候,watchFetchRequests 会继续监听其它的 watchFetchRequests actions。当然,JavaScript 是单线程的,redux-saga 让事情看起来是同时进行的。

(3)在 worker saga fetchUrl 中,call(fetch,url) 指示中间件去调用 fetch 函数,同时,会阻塞fetchUrl 的执行,中间件会停止 generator 函数,直到 fetch 返回的 Promise 被 resolved(或 rejected),然后才恢复执行 generator 函数。

最后,总结一下 redux-saga 的优点:

(1)声明式 Effects:所有的操作以JavaScript对象的方式被 yield,并被 middleware 执行。使得在 saga 内部测试变得更加容易,可以通过简单地遍历 Generator 并在 yield 后的成功值上面做一个 deepEqual 测试。
(2)高级的异步控制流以及并发管理:可以使用简单的同步方式描述异步流,并通过 fork 实现并发任务。
(3)架构上的优势:将所有的异步流程控制都移入到了 sagas,UI 组件不用执行业务逻辑,只需 dispatch action 就行,增强组件复用性。

详细代码可以查看分支:https://github.com/YahuiWong/react-native-typescript/tree/redux-saga

参考:
https://segmentfault.com/a/1190000007248878#articleHeader7

什么是.NET?什么是.NET Framework?本文将从上往下,循序渐进的介绍一系列相关.NET的概念,先从类型系统开始讲起,我将通过跨语言操作这个例子来逐渐引入一系列.NET的相关概念,这主要包括:CLS、CTS(CLI)、FCL、Windows下CLR的相关核心组成、Windows下托管程序运行概念、什么是.NET Framework,.NET Core,.NET Standard及一些VS编译器相关杂项和相关阅读链接。完整的从上读到下则你可以理解个大概的.NET体系。

想看到全文 请打开:https://www.cnblogs.com/1996V/p/9037603.html

上次我们说到.Net Core 自动化部署:使用docker版jenkins部署dotnetcore应用,这次我们使用jenkins发布我们的.NET Core站点到docker容器中运行,为后面的的docker集群化部署做准备

jenkins 安装并配置必要的发布插件 Publish Over SSH Plugin

因为linux下ssh连接使用更方便快捷,所以这里建议使用ssh发布插件来完成发布操作

  1. 在插件中心搜索Publish Over SSH关键字可以找到这个插件,安装它然后重启jenkins

  2. 进入 系统管理->系统设置->Publish over SSH 根据您的发布目标服务器的情况配置ip地址 key 和Remote Directory
    注意:Remote Directory既是您发布任务指定目录的根目录/,发布任务的远程目录是以Remote Directory为基础的。

在生产环境部署docker脚本

我已经做了个自动启动和重新构建的docker-compose项目
项目地址是:https://github.com/YahuiWong/docker-netcore

使用方法:

1
2
git clone https://github.com/YahuiWong/docker-netcore
cd docker-netcore
  1. release publish your project to ./publish dir
  2. run docker-compose down remove earlier image & container
  3. run docker-compose build --no-cache build with no-cache
  4. docker-compose up -d

编写代码发布任务

代码发布的代码获取和生成部分我们这次就不详细说明了,可以到.Net Core 自动化部署:使用docker版jenkins部署dotnetcore应用查看,这里着重讲解Publish over SSH在发布任务的配置

  1. 添加构建后操作新增选项 Send build artifacts over SSH
  2. SSH Server Name选择自己配置好的ssh服务
  3. Source filesRemove prefix和之前的配置一样,这里不细说
  4. Remote directory选择ssh服务器 /docker-netcore/publish 路径
  5. Exec command 填写
1
2
3
4
cd /data/tests/docker-netcore # 进入您的docker-compose.yml位置
docker-compose down
docker-compose build --no-cache
docker-compose up -d

保存您的发布任务,开始发布,运行成功。

什么是ELK

ELK是三个开源软件的缩写,分别表示:Elasticsearch , Logstash, Kibana , 它们都是开源软件。新增了一个FileBeat,它是一个轻量级的日志收集处理工具(Agent),Filebeat占用资源少,适合于在各个服务器上搜集日志后传输给Logstash,官方也推荐此工具。

Elasticsearch

Elasticsearch是个开源分布式搜索引擎,提供搜集、分析、存储数据三大功能。它的特点有:分布式,零配置,自动发现,索引自动分片,索引副本机制,restful风格接口,多数据源,自动搜索负载等。

Logstash

Logstash 主要是用来日志的搜集、分析、过滤日志的工具,支持大量的数据获取方式。一般工作方式为c/s架构,client端安装在需要收集日志的主机上,server端负责将收到的各节点日志进行过滤、修改等操作在一并发往elasticsearch上去。

Kibana

Kibana 也是一个开源和免费的工具,Kibana可以为 Logstash 和 ElasticSearch 提供的日志分析友好的 Web 界面,可以帮助汇总、分析和搜索重要数据日志。

如何使用ELK

ELK环境快速搭建

这里推荐使用docker-compose一键搭建 地址:https://github.com/deviantony/docker-elk.git

使用方法:

1
2
3
git clone https://github.com/deviantony/docker-elk.git
cd docker-elk
docker-compose up -d

安装完之后,浏览器上访问安装服务器的ip:5601 (注意端口号)可以打开kibana管理后台

注意:在logstash/pipeline/logstash.conf您的logstashinput配置是 tcp 5000 后面我们会用到。

net core项目中使用

代码项目中添加

项目引用NlognugetNLog.Extensions.Logging

Startup.cs中添加nlog启动

1
2
3
4
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddNLog();//添加NLog
……

在项目的 nlog.config文件中targets节点
添加子target

1
2
3
4
5
6
7
<!-- Tcp日志target -->
<target xsi:type="Network"
name="ownLog-tcp"
keepConnection="false"
address ="tcp://ELK服务器ip:5000"
layout="#${longdate}#${nodeName}#${logger}#${uppercase:${level}}#${callsite}#${callsite-linenumber}#${aspnet-request-url}#${aspnet-request-method}#${aspnet-mvc-controller}#${aspnet-mvc-action}#${message}#${exception:format=ToString}#"
/>

rules节点添加配置

1
<logger name="*" minlevel="Trace" writeTo="ownLog-tcp" />

启动项目,生成日志

配置kibana 添加index pattern

进入刚刚搭建好的kibana后台,按照指引创建一个index pattern
然后 discover你的log吧

脚本如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
-- CREATE FUNCTION fn_Index_CreateIndexName
--drop FUNCTION [dbo].[fn_Index_CreateIndexName];
CREATE FUNCTION [dbo].[fn_Index_CreateIndexName] (@equality_columns NVARCHAR(4000),@Inequality_columns NVARCHAR(4000), @index_handlE INT) RETURNS VARCHAR(128)
AS
BEGIN

DECLARE @IndexName NVARCHAR(MAX)

SET @IndexName = ISNULL(@equality_columns,@Inequality_columns)

SET @IndexName = LTRIM(REPLACE(@IndexName,'[','_'))

SET @IndexName = RTRIM(REPLACE(@IndexName,']','_'))

SET @IndexName = REPLACE(@IndexName,',','')

SET @IndexName = REPLACE(@IndexName,'_ _','_')

IF LEN(@IndexName) > 120
BEGIN

SET @IndexName = SUBSTRING(@IndexName,0,120)

END

SET @IndexName = @IndexName + CAST(@index_handlE AS NVARCHAR(15))

RETURN @IndexName
END

GO

-- CREATE FUNCTION vw_Index_MissingIndex
--drop VIEW [dbo].[vw_Index_MissingIndex]
CREATE VIEW [dbo].[vw_Index_MissingIndex]

AS
SELECT '[' + d.name + ']' as DBName,
[dbo].[fn_Index_CreateIndexName](mid.equality_columns,mid.Inequality_columns,mid.index_handlE) AS ID,
REPLACE(mid.equality_columns,',',' ASC,') AS equality_columns,
REPLACE(mid.Inequality_columns,',',' ASC,') AS Inequality_columns,
mid.Included_columns,
mid.[statement]
FROM sys.dm_db_missing_index_details mid
INNER JOIN sys.databases d
on d.database_id = mid.database_id

GO
--Drop PROCEDURE [dbo].[usp_Index_MissingIndexCreationStatements];
CREATE PROCEDURE [dbo].[usp_Index_MissingIndexCreationStatements]
AS

DECLARE @IndexCreationPlaceholder_Start AS NVARCHAR(MAX)
DECLARE @IndexCreationPlaceholder_End AS NVARCHAR(MAX)

-- PREPARE PLACEHOLDER

SET @IndexCreationPlaceholder_Start = 'IF NOT EXISTS
(SELECT * FROM {2}.sys.indexes WHERE [name] = ''IX_{0}'' )
BEGIN
CREATE NONCLUSTERED INDEX [IX_{0}] ON {1}'

SET @IndexCreationPlaceholder_End = ' WITH (PAD_INDEX = OFF,
STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF,
ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
END;' + char(13) + char(10)

-- STATEMENT CREATION

SELECT
DBName,
CASE
WHEN NOT mid.equality_columns IS NULL AND NOT mid.Inequality_columns IS NULL THEN
REPLACE(REPLACE(REPLACE(@IndexCreationPlaceholder_Start,'{0}', mid.ID),'{1}',mid.[statement]),'{2}',mid.DBName)
+ '
( ' +
COALESCE(mid.equality_columns,'') +
' ASC,' +
COALESCE(mid.Inequality_columns,'') +
' ASC
)' +
COALESCE('INCLUDE ( ' + mid.Included_columns + ' ) ','')
+ @IndexCreationPlaceholder_End

WHEN mid.equality_columns IS NULL AND NOT mid.Inequality_columns IS NULL THEN
REPLACE(REPLACE(REPLACE(@IndexCreationPlaceholder_Start,'{0}', mid.ID),'{1}',mid.[statement]),'{2}',mid.DBName)
+ '
( ' +
COALESCE(mid.Inequality_columns,'') +
' ASC
) ' +
COALESCE('INCLUDE ( ' + mid.Included_columns + ' ) ','')
+ @IndexCreationPlaceholder_End

WHEN NOT mid.equality_columns IS NULL AND mid.Inequality_columns IS NULL THEN
REPLACE(REPLACE(REPLACE(@IndexCreationPlaceholder_Start,'{0}', mid.ID),'{1}',mid.[statement]),'{2}',mid.DBName)
+ '
( ' +
COALESCE(mid.equality_columns,'') + ' ASC
) ' +
COALESCE('INCLUDE ( ' + mid.Included_columns + ' ) ','')
+ @IndexCreationPlaceholder_End
ELSE NULL
END AS Index_Creation_Statement,
' DROP INDEX [IX_' + mid.ID + '] ON ' + mid.[statement] + + char(13) + char(10) AS Index_Drop_Statement
FROM [dbo].[vw_Index_MissingIndex] AS mid

GO

脚本如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
USE YOUR_DBNAME;  
DECLARE @name varchar(100)

DECLARE authors_cursor CURSOR FOR
Select [name] from sysobjects where xtype='u' order by id

OPEN authors_cursor

FETCH NEXT FROM authors_cursor INTO @name

WHILE @@FETCH_STATUS = 0
BEGIN
DBCC DBREINDEX (@name, '', 90)
print @name
FETCH NEXT FROM authors_cursor
INTO @name
END

deallocate authors_cursor