Dephi时间戳与日期互转 - CSDN博客

mikel阅读(1588)

1、日期转换成时间戳function Gettimestamp: string; begin    Result := inttostr(DateTimeToUnix(IncHour(Now,-8)));    //  本地时间减8小时end;2、时间戳转换成日期function UnixDateToDateTime(const USec: Longin

来源: 时间戳与日期互转 – CSDN博客

1、日期转换成时间戳

function Gettimestamp: string;
begin
Result := inttostr(DateTimeToUnix(IncHour(Now,-8)));    //  本地时间减8小时
end;

2、时间戳转换成日期

function UnixDateToDateTime(const USec: Longint): TDateTime;
const
UnixStartDate: TDateTime = 25569.0;      // 1970/01/01
begin
Result := (Usec / 86400) + UnixStartDate;
Result  := IncHour(Result,8);
end;

Deprecated: Automatically populating $HTTP_RAW_POST_DATA is deprecated and will be removed in a futu - CSDN博客

mikel阅读(1058)

Deprecated: Automatically populating $HTTP_RAW_POST_DATA is deprecated and will be removed in a future version. To avoid this warning set ” to ‘-1’ in php.ini and use the php://input stream instead.

来源: Deprecated: Automatically populating $HTTP_RAW_POST_DATA is deprecated and will be removed in a futu – CSDN博客

Deprecated: Automatically populating $HTTP_RAW_POST_DATA is deprecated and will be removed in a future version. To avoid this warning set ” to ‘-1’ in php.ini and use the php://input stream instead. in Unknown on line 0`

报这样的错误很多情况下都是php版本的问题, 我是在5.6版本中使用ajax时遇到的,原因是$HTTP_RAW_POST_DATA 要逐渐弃用,在php5.6版本中找到php.ini文件,将always_populate_raw_post_data改成-1,并且打开注释,OK,解决

wampserver 最新版本 mysql修改数据库密码 - CSDN博客

mikel阅读(1245)

第一步 进入mySQL 控制台 wamp安装,数据库是没有密码 进入控制台直接回车就可以了第二步 使用 update user set password=PASSWORD(‘你所要修改的密码’) where user=’root’; 注 : 分号、引号 都不要省去 如果报错了 不要急 新版本有些变动 前面两步完成了 密码还没有生效 需要使用下面命令

来源: wampserver 最新版本 mysql修改数据库密码 – CSDN博客

第一步 进入mySQL 控制台
这里写图片描述
wamp安装,数据库是没有密码 进入控制台直接回车就可以了

第二步 使用 update user set password=PASSWORD(‘你所要修改的密码’) where user=’root’;
注 : 分号、引号 都不要省去
这里写图片描述

如果报错了 不要急  新版本有些变动  
  • 1
  • 2

这里写图片描述

前面两步完成了 密码还没有生效 需要使用下面命令 刷新表 flush privileges; 从而使密码生效

最后 使用quit;退出 
  • 1
  • 2

如果你是用 phpmyadmin 访问数据库的话 还需要 修改 wamp/apps/phpmyadmin 中的配置文件
config.inc.php中

$cfg['Servers'][$i]['password'] = '你修改的数据库密码';
  • 1

保存就可以了

Using PHP OCI8 with 32-bit PHP on Windows 64-bit | Oracle Scripting and Oracle: Christopher Jones Blog

mikel阅读(955)

来源: Using PHP OCI8 with 32-bit PHP on Windows 64-bit | Oracle Scripting and Oracle: Christopher Jones Blog

The world migration from 32-bit to 64-bit operating systems is gaining pace. However I’ve seen a couple of customers having difficulty with the PHP OCI8 extension and Oracle DB on Windows 64-bit platforms. The errors vary depending how PHP is run. They may appear in the Apache or PHP log:

Unable to load dynamic library 'C:\Program Files
(x86)\PHP\ext\php_oci8_11g.dll' - %1 is not a valid Win32
application.

or

Warning oci_connect(): OCIEnvNlsCreate() failed. There is
something wrong with your system - please check that PATH includes the
directory with Oracle Instant Client libraries

Other than IIS permission issues a common cause seems to be trying to use PHP with libraries from an Oracle 64-bit database on the same machine. There is currently no 64-bit version of PHP on http://php.net/ so there is a library mismatch.

A solution is to install Oracle Instant Client 32-bit and make sure that PHP uses these libraries, while not interferring with the 64-bit database on the same machine. Warning: The following hacky steps come untested from a Linux user:

  1. Unzip Oracle Instant Client 32-bit and move it to C:\WINDOWS\SYSWOW64\INSTANTCLIENT_11_2. You may need to do this in a console with elevated permissions.
  2. Edit your PATH environment variable and insert C:\WINDOWS\SYSTEM32\INSTANTCLIENT_11_2in the directory list before the entry for the Oracle Home library.

    Windows makes it so all 32-bit applications that reference C:\WINDOWS\SYSTEM32 actually see the contents of the C:\WINDOWS\SYSWOW64 directory. Your 64-bit database won’t find an Instant Client in the real, physical C:\WINDOWS\SYSTEM32 directory and will continue to use the database libraries.

Some of our Windows team are concerned about this hack and prefer a more “correct” solution that (i) doesn’t require changing the Windows system directory (ii) doesn’t add to the “memory” burden about what was configured on the system (iii) works when there are multiple database versions installed. The solution is to write a script which will set the 64-bit (or 32-bit) Oracle libraries in the path as needed before invoking the relevant bit-ness application. This does have a weakness when the application is started as a service.

As a footnote: If you don’t have a local database and simply need to have 32-bit and 64-bit Instant Client accessible at the same time, try the “symbolic” link approach covered in the hack in this OTN forum thread.

Reminder warning: This blog post came untested from a Linux user.

新安装的wampserver怎么使用本机已有的mysql作为数据库 - gccbuaa - 博客园

mikel阅读(782)

来源: 新安装的wampserver怎么使用本机已有的mysql作为数据库 – gccbuaa – 博客园

一般在一台没有安装mySQL的机器上安装好wamp后,能够直接在wamp的phpMyAdmin中打开集成的mySQL并设置用户信息。

而假设之前已经安装配置好mySQL(实usernamepassword),之后才安装wamp的话,wamp的mysql会与本机mysql产生冲突,
导致顶开phpMyAdmin的时候会报错,错误信息大致是“用户root未使用password进行登录”。

分析一下原因能够知道,phpMyAdmin会读电脑环境变量中的mysql的路径,而环境变量中已经存在了一条老mysql的路径。
在安装wamp后,wamp就会读取这条老的mysql路径而不会读取自带集成mysql的路径。可是wamp仍然会使用自己集成mysql的配置信息(新安装的wamp的mysql配置信息没有password),
终于导致用集成mysql的配置信息去訪问老mysql的数据库,所以就会报错。

网上其它的解决的方法大致有两种:一种是备份好老的mysql信息,然后卸载掉,把数据转移到集成mysql中。还有一种是改变老mysql的port号。防止两个mysql冲突

而笔者给大家带来的方法是直接改变集成Mysql的配置信息,用以訪问本机已经存在的Mysql,经笔者实验,这样的方法相当方便。
方法例如以下
在D:\wamp\apps\phpmyadmin4.1.14下编辑config.inc.php
找到以下两句话

$cfg['Servers'][$i]['user'] = 'root';
$cfg['Servers'][$i]['password'] = '';

将他们的值改成本机mysql的username和password。

重新启动wamp全部服务,再次打开phpMyAdmin的时候就能訪问mysql了

PHP: 可变变量 - Manual

mikel阅读(830)

来源: PHP: 可变变量 – Manual

有时候使用可变变量名是很方便的。就是说,一个变量的变量名可以动态的设置和使用。一个普通的变量通过声明来设置,例如:

<?php
$a = 'hello';
?>

一个可变变量获取了一个普通变量的值作为这个可变变量的变量名。在上面的例子中 hello 使用了两个美元符号($)以后,就可以作为一个可变变量的变量了。例如:

<?php
$$a = 'world';
?>

这时,两个变量都被定义了:$a 的内容是“hello”并且 $hello 的内容是“world”。因此,以下语句:

<?php
echo "$a ${$a}";
?>

与以下语句输出完全相同的结果:

<?php
echo "$a $hello";
?>

它们都会输出:hello world

要将可变变量用于数组,必须解决一个模棱两可的问题。这就是当写下 $$a[1] 时,解析器需要知道是想要 $a[1]作为一个变量呢,还是想要 $$a 作为一个变量并取出该变量中索引为 [1] 的值。解决此问题的语法是,对第一种情况用 ${$a[1]},对第二种情况用 ${$a}[1]

类的属性也可以通过可变属性名来访问。可变属性名将在该调用所处的范围内被解析。例如,对于 $foo->$bar 表达式,则会在本地范围来解析 $bar 并且其值将被用于 $foo 的属性名。对于 $bar 是数组单元时也是一样。

也可使用花括号来给属性名清晰定界。最有用是在属性位于数组中,或者属性名包含有多个部分或者属性名包含有非法字符时(例如来自 json_decode() 或 SimpleXML)。

Example #1 可变属性示例

<?php
class foo {
var $bar = 'I am bar.';
var $arr = array('I am A.', 'I am B.', 'I am C.');
var $r   = 'I am r.';
}

$foo = new foo();
$bar = 'bar';
$baz = array('foo', 'bar', 'baz', 'quux');
echo $foo->$bar . "\n";
echo $foo->$baz[1] . "\n";

$start = 'b';
$end   = 'ar';
echo $foo->{$start . $end} . "\n";

$arr = 'arr';
echo $foo->$arr[1] . "\n";
echo $foo->{$arr}[1] . "\n";

?>

以上例程会输出:

I am bar.
I am bar.
I am bar.
I am r.
I am B.

Blob、FileReader全面解析 - CSDN博客

mikel阅读(1384)

上传图片获取base64图片或2进制图片base64:var uploadFile = document.getElementById(‘uploadFile’); // uploadFile.onchange = function() { var fr = new FileReader(); fr.onloadend = function(res)

来源: Blob、FileReader全面解析 – CSDN博客

历史上,JavaScript无法处理二进制数据。如果一定要处理的话,只能使用charCodeAt()方法,一个个字节地从文字编码转成二进制数据,还有一种办法是将二进制数据转成Base64编码,再进行处理。这两种方法不仅速度慢,而且容易出错。ECMAScript 5引入了Blob对象,允许直接操作二进制数据。

Blob对象是一个代表二进制数据的基本对象,在它的基础上,又衍生出一系列相关的API,用来操作文件。

  • File对象:负责处理那些以文件形式存在的二进制数据,也就是操作本地文件;
  • FileList对象:File对象的网页表单接口;
  • FileReader对象:负责将二进制数据读入内存内容;
  • URL对象:用于对二进制数据生成URL。

Blob对象

Blob(Binary Large Object)对象代表了一段二进制数据,提供了一系列操作接口。其他操作二进制数据的API(比如File对象),都是建立在Blob对象基础上的,继承了它的属性和方法。

生成Blob对象有两种方法:一种是使用Blob构造函数,另一种是对现有的Blob对象使用slice方法切出一部分。

(1)Blob构造函数,接受两个参数。第一个参数是一个包含实际数据的数组,第二个参数是数据的类型,这两个参数都不是必需的。

var htmlParts = ["<a id=\"a\"><b id=\"b\">hey!<\/b><\/a>"];
var myBlob = new Blob(htmlParts, { "type" : "text\/xml" });

下面是一个利用Blob对象,生成可下载文件的例子。

var blob = new Blob(["Hello World"]);

var a = document.createElement("a");
a.href = window.URL.createObjectURL(blob);
a.download = "hello-world.txt";
a.textContent = "Download Hello World!";

body.appendChild(a);

上面的代码生成了一个超级链接,点击后提示下载文本文件hello-world.txt,文件内容为“Hello World”。

(2)Blob对象的slice方法,将二进制数据按照字节分块,返回一个新的Blob对象。

var newBlob = oldBlob.slice(startingByte, endindByte);

下面是一个使用XMLHttpRequest对象,将大文件分割上传的例子。

function upload(blobOrFile) {
  var xhr = new XMLHttpRequest();
  xhr.open('POST', '/server', true);
  xhr.onload = function(e) { ... };
  xhr.send(blobOrFile);
}

document.querySelector('input[type="file"]').addEventListener('change', function(e) {
  var blob = this.files[0];

  const BYTES_PER_CHUNK = 1024 * 1024; // 1MB chunk sizes.
  const SIZE = blob.size;

  var start = 0;
  var end = BYTES_PER_CHUNK;

  while(start < SIZE) {
    upload(blob.slice(start, end));

    start = end;
    end = start + BYTES_PER_CHUNK;
  }
}, false);

})();

(3)Blob对象有两个只读属性:

  • size:二进制数据的大小,单位为字节。
  • type:二进制数据的MIME类型,全部为小写,如果类型未知,则该值为空字符串。

在Ajax操作中,如果xhr.responseType设为blob,接收的就是二进制数据。

FileList对象

FileList对象针对表单的file控件。当用户通过file控件选取文件后,这个控件的files属性值就是FileList对象。它在结构上类似于数组,包含用户选取的多个文件。

<input type="file" id="input" onchange="console.log(this.files.length)" multiple />

当用户选取文件后,就可以读取该文件。

var selected_file = document.getElementById('input').files[0];

采用拖放方式,也可以得到FileList对象。

var dropZone = document.getElementById('drop_zone');
dropZone.addEventListener('drop', handleFileSelect, false);

function handleFileSelect(evt) {
    evt.stopPropagation();
    evt.preventDefault();

    var files = evt.dataTransfer.files; // FileList object.

    // ...
}

上面代码的 handleFileSelect 是拖放事件的回调函数,它的参数evt是一个事件对象,该参数的dataTransfer.files属性就是一个FileList对象,里面包含了拖放的文件。

File API

File API提供File对象,它是FileList对象的成员,包含了文件的一些元信息,比如文件名、上次改动时间、文件大小和文件类型。

var selected_file = document.getElementById('input').files[0];

var fileName = selected_file.name;
var fileSize = selected_file.size;
var fileType = selected_file.type;

File对象的属性值如下。

  • name:文件名,该属性只读。
  • size:文件大小,单位为字节,该属性只读。
  • type:文件的MIME类型,如果分辨不出类型,则为空字符串,该属性只读。
  • lastModified:文件的上次修改时间,格式为时间戳。
  • lastModifiedDate:文件的上次修改时间,格式为Date对象实例。
$('#upload-file').files[0]
// {
//   lastModified: 1449370355682,
//   lastModifiedDate: Sun Dec 06 2015 10:52:35 GMT+0800 (CST),
//   name: "HTTP 2 is here Goodbye SPDY Not quite yet.png",
//   size: 17044,
//   type: "image/png"
// }

FileReader API

FileReader API用于读取文件,即把文件内容读入内存。它的参数是File对象或Blob对象。

对于不同类型的文件,FileReader提供不同的方法读取文件。

  • readAsBinaryString(Blob|File):返回二进制字符串,该字符串每个字节包含一个0到255之间的整数。
  • readAsText(Blob|File, opt_encoding):返回文本字符串。默认情况下,文本编码格式是’UTF-8’,可以通过可选的格式参数,指定其他编码格式的文本。
  • readAsDataURL(Blob|File):返回一个基于Base64编码的data-uri对象。
  • readAsArrayBuffer(Blob|File):返回一个ArrayBuffer对象。

readAsText方法用于读取文本文件,它的第一个参数是FileBlob对象,第二个参数是前一个参数的编码方法,如果省略就默认为UTF-8编码。该方法是异步方法,一般监听onload件,用来确定文件是否加载结束,方法是判断FileReader实例的result属性是否有值。其他三种读取方法,用法与readAsText方法类似。

var reader = new FileReader();
reader.onload = function(e) {
  var text = reader.result;
}

reader.readAsText(file, encoding);

readAsDataURL方法返回一个data URL,它的作用基本上是将文件数据进行Base64编码。你可以将返回值设为图像的src属性。

var file = document.getElementById('destination').files[0];
if(file.type.indexOf('image') !== -1) {
  var reader = new FileReader();
  reader.onload = function (e) {
    var dataURL = reader.result;
  }
  reader.readAsDataURL(file);
}

readAsBinaryString方法可以读取任意类型的文件,而不仅仅是文本文件,返回文件的原始的二进制内容。这个方法与XMLHttpRequest.sendAsBinary方法结合使用,就可以使用JavaScript上传任意文件到服务器。

var reader = new FileReader();
reader.onload = function(e) {
  var rawData = reader.result;
}
reader.readAsBinaryString(file);

readAsArrayBuffer方法读取文件,返回一个类型化数组(ArrayBuffer),即固定长度的二进制缓存数据。在文件操作时(比如将JPEG图像转为PNG图像),这个方法非常方便。

var reader = new FileReader();
reader.onload = function(e) {
  var arrayBuffer = reader.result;
}

reader.readAsArrayBuffer(file);

除了以上四种不同的读取文件方法,FileReader API还有一个abort方法,用于中止文件上传。

var reader = new FileReader();
reader.abort();

FileReader对象采用异步方式读取文件,可以为一系列事件指定回调函数。

  • onabort方法:读取中断或调用reader.abort()方法时触发。
  • onerror方法:读取出错时触发。
  • onload方法:读取成功后触发。
  • onloadend方法:读取完成后触发,不管是否成功。触发顺序排在 onload 或 onerror 后面。
  • onloadstart方法:读取将要开始时触发。
  • onprogress方法:读取过程中周期性触发。

下面的代码是如何展示文本文件的内容。

var reader = new FileReader();
reader.onload = function(e) {
  console.log(e.target.result);
}
reader.readAsText(blob);

onload事件的回调函数接受一个事件对象,该对象的target.result就是文件的内容。

下面是一个使用readAsDataURL方法,为img元素添加src属性的例子。

var reader = new FileReader();
reader.onload = function(e) {
  document.createElement('img').src = e.target.result;
};
reader.readAsDataURL(f);

下面是一个onerror事件回调函数的例子。

var reader = new FileReader();
reader.onerror = errorHandler;

function errorHandler(evt) {
  switch(evt.target.error.code) {
    case evt.target.error.NOT_FOUND_ERR:
      alert('File Not Found!');
      break;
    case evt.target.error.NOT_READABLE_ERR:
      alert('File is not readable');
      break;
    case evt.target.error.ABORT_ERR:
      break;
    default:
      alert('An error occurred reading this file.');
  };
}

下面是一个onprogress事件回调函数的例子,主要用来显示读取进度。

var reader = new FileReader();
reader.onprogress = updateProgress;

function updateProgress(evt) {
  if (evt.lengthComputable) {
    var percentLoaded = Math.round((evt.loaded / evt.totalEric Bidelman) * 100);
    var progress = document.querySelector('.percent');
    if (percentLoaded < 100) {
      progress.style.width = percentLoaded + '%';
      progress.textContent = percentLoaded + '%';
    }
  }
}

读取大文件的时候,可以利用Blob对象的slice方法,将大文件分成小段,逐一读取,这样可以加快处理速度。

综合实例:显示用户选取的本地图片

假设有一个表单,用于用户选取图片。

<input type="file" name="picture" accept="image/png, image/jpeg"/>

一旦用户选中图片,将其显示在canvas的函数可以这样写:

document.querySelector('input[name=picture]').onchange = function(e){
     readFile(e.target.files[0]);
}

function readFile(file){

  var reader = new FileReader();

  reader.onload = function(e){
    applyDataUrlToCanvas( reader.result );
  };

  reader.reaAsDataURL(file);
}

还可以在canvas上面定义拖放事件,允许用户直接拖放图片到上面。

// stop FireFox from replacing the whole page with the file.
canvas.ondragover = function () { return false; };

// Add drop handler
canvas.ondrop = function (e) {
  e.stopPropagation();
  e.preventDefault(); 
  e = e || window.event;
  var files = e.dataTransfer.files;
  if(files){
    readFile(files[0]);
  }
};

所有的拖放事件都有一个dataTransfer属性,它包含拖放过程涉及的二进制数据。

还可以让canvas显示剪贴板中的图片。

document.onpaste = function(e){
  e.preventDefault();
  if(e.clipboardData&&e.clipboardData.items){
    // pasted image
    for(var i=0, items = e.clipboardData.items;i<items.length;i++){
      if( items[i].kind==='file' && items[i].type.match(/^image/) ){
        readFile(items[i].getAsFile());
        break;
      }
    }
  }
  return false;
};

URL对象

URL对象用于生成指向File对象或Blob对象的URL。

var objecturl =  window.URL.createObjectURL(blob);

上面的代码会对二进制数据生成一个URL,类似于“blob:http%3A//test.com/666e6730-f45c-47c1-8012-ccc706f17191”。这个URL可以放置于任何通常可以放置URL的地方,比如img标签的src属性。需要注意的是,即使是同样的二进制数据,每调用一次URL.createObjectURL方法,就会得到一个不一样的URL。

这个URL的存在时间,等同于网页的存在时间,一旦网页刷新或卸载,这个URL就失效。除此之外,也可以手动调用URL.revokeObjectURL方法,使URL失效。

window.URL.revokeObjectURL(objectURL);

下面是一个利用URL对象,在网页插入图片的例子。

var img = document.createElement("img");

img.src = window.URL.createObjectURL(files[0]);

img.height = 60;

img.onload = function(e) {
    window.URL.revokeObjectURL(this.src);
}

body.appendChild(img);

var info = document.createElement("span");

info.innerHTML = files[i].name + ": " + files[i].size + " bytes";

body.appendChild(info);

还有一个本机视频预览的例子。

var video = document.getElementById('video');
var obj_url = window.URL.createObjectURL(blob);
video.src = obj_url;
video.play()
window.URL.revokeObjectURL(obj_url);

【转】Oracle + PHP Cookbook(php oracle clob 长度超过4000如何写入) - yzyssg1的博客 - CSDN博客

mikel阅读(758)

 

来源: 【转】Oracle + PHP Cookbook(php oracle clob 长度超过4000如何写入) – yzyssg1的博客 – CSDN博客

在甲骨文LOB和PHP工作
由哈里Fuecks

达到4,000字节的限制?输入LOB …

 

在这个“Oracle + PHP Cookbook”HowTo中,您将学习可用的LOB类型和与之相关的问题,然后探索PHP中常见的LOB操作的示例。使用像VARCHAR2这样的Oracle类型是很好的,但是如果你需要能够一次存储超过4,000字节的限制呢?对于此任务,您需要一个Oracle的长对象(LOB)类型,这反过来要求您了解如何使用PHP API来处理LOB。这本身对于那些不熟悉它的人来说是令人生畏的。

Oracle中的长对象

Oracle提供以下LOB类型:

  • BLOB,用于存储二进制数据
  • CLOB,用于存储使用数据库字符集编码的字符数据
  • NCLOB,用于存储使用国家字符集的Unicode字符数据。需要注意的是NCLOBs是,目前不被支持PHP OCI8扩展,你会在这里使用。
  • BFILE,用于引用操作系统文件系统下的外部文件

LOB的另一个子类是临时LOB,它可以是BLOB,CLOB或NCLOB,但存储在临时表空间中,直到您释放它。请注意,旧版本的Oracle分别为字符和二进制数据提供了LONG和LONG RAW类型。随着Oracle9需要这些赞成的LOB被弃用。

LOB存储。对于BLOB,CLOB和NCLOB类型,Oracle数据库10 ğ能够在一个单一的值存储高达128TB,这取决于你的数据库块大小和“块”设置,为LOB定义的。

LOB本身包括两个元素:LOB内容和LOB定位符,其是到LOB内容的“指针”。这种分离需要允许Oracle存储和有效地管理LOB和它反映在使用到PHP的API INSERT, 数据库,和 选择的LOB(见下文)。

对于内部LOB类型(即不是BFILE),如果LOB的大小小于4KB,则Oracle将在表中存储LOB的内容以及行的其余部分。大于4KB的LOB在默认情况下在表的表空间中存储为“out-of-line”。此方法允许快速检索小LOB,而对于大LOB,访问时间将较慢,但是在扫描表时的整体性能被保留。

还有LOB存储和访问的其他选项,例如内存缓存和缓冲 – 这可以提高性能,具体取决于您的应用程序的具体情况。欲了解更多信息,请参阅 LOB性能指南和 Oracle数据库应用程序开发人员指南-大型对象在Oracle文档中获得。

LOB的限制。许多限制适用于使用LOB类型,最重要的是它们在SQL语句中的使用。您不能在以下任何查询中使用LOB类型。

SELECT DISTINCT <lob_type>
ORDER BY <lob_type>
GROUP BY <lob_col>

这也是非法的表连接,使用LOB类型列 UNION, INTERSECTION和 MINUS语句。其他限制适用于LOB使用的其他方面,例如,您不能将LOB用作主键列。再次,看 Oracle数据库应用程序开发人员指南-大型对象的详细信息。

CLOB和字符集

数据库的默认字符集由参数NLS_CHARACTERSET定义,并且放置在CLOB中的文本应使用此字符集进行编码。使用此SQL来确定您的数据库字符集编码:

SELECT value FROM nls_database_parameters WHERE parameter ='NLS_CHARACTERSET'

由于缺乏对PHP中NCLOB的支持,您可能需要考虑使用Unicode编码作为数据库字符,例如UTF-8,可以使用以下语句完成(给予足够的权限):

ALTER数据库字符集UTF8

注意:不要在不理解影响的情况下尝试此操作,尤其是如果现有数据或应用程序代码使用不同的字符集。看到 甲骨文全球化支持指南对全球化的Oracle PHP应用程序概述了解更多信息。使用LOB

这里的讨论将集中在PHP的OCI8扩展。还值得注意的是,Oracle提供了DBMS_LOB包,其中包含使用PL / SQL处理LOB的并行过程和函数。

PHP OCI8扩展在全局PHP命名空间中注册了一个名为“OCI-Lob”的PHP类。当您执行 SELECT语句,例如,其中一列是一个LOB类型,PHP将自动绑定这个到OCI-LOB对象实例。一旦你有一个OCI高球对象的引用,你可以调用方法一样 的load()和 save()方法来访问或修改LOB的内容。

可用的OCI高球的方法将取决于你的PHP版本,PHP5特别是具有像获得方法 的read() , 求()和 追加() 。在 PHP手册是有点不清楚,在这种情况下,版本号,所以如果有疑问,您可以验证使用下面的脚本。

<?php
foreach(get_class_methods('OCI-Lob')as $ method){
    print“OCI-Lob :: $ method()\ n”;
}}
?>

在我的系统上,运行PHP 5.0.5,我得到以下列表的方法:

OCI-Lob :: load()
OCI-Lob :: tell()
OCI-Lob :: truncate()
OCI-Lob :: erase()
OCI-Lob :: flush()
OCI-Lob :: setbuffering()
OCI-Lob :: getbuffering()
OCI-Lob :: rewind()
OCI-Lob :: read()
OCI-Lob :: eof()
OCI-Lob :: seek()
OCI-Lob :: write()
OCI-Lob :: append()
OCI-Lob :: size()
OCI-Lob :: writetofile()
OCI-Lob :: writetemporary()
OCI-Lob :: close()
OCI-Lob :: save()
OCI-Lob :: savefile()
OCI-Lob :: free()

在实践中,PHP 4.x OCI8扩展仅支持读取或写入完整的LOB,这是Web应用程序中最常见的用例。PHP5扩展是为了让LOB的“块”的阅读和写作,以及支持LOB缓冲的方法 setBuffering()和 getBuffering() 。PHP5还提供了独立的功能 oci_lob_is_equal()和 oci_lob_copy() 。此处的示例将使用新的PHP5 OCI函数名(如 oci_parse而不是 OCIParse)。示例使用以下序列和表:

CREATE SEQUENCE mylobs_id_seq
    NOMINVALUE
    NOMAXVALUE
    NOCYCLE
    CACHE 20
    NOORDER
增量1;

CREATE TABLE mylobs(
    id NUMBER PRIMARY KEY,
    mylob CLOB
)

注意,这里的大多数示例使用CLOB,但是相同的逻辑也可以几乎完全应用于BLOB。插入LOB

要 INSERT内部LOB,首先需要使用相应的Oracle初始化LOB EMPTY_BLOB或 EMPTY_CLOB功能,您无法更新一个包含NULL值的LOB。

初始化后,你再绑定列到PHP OCI-LOB对象和更新通过对象的LOB的内容 保存()方法。

下面的脚本提供了一个示例,返回从该LOB类型 INSERT查询:

<?php
//连接到DB等...

$ sql =“INSERT INTO
        mylobs
          ((
            ID,
            mylob
          )
       值
          ((
            mylobs_id_seq.NEXTVAL,
            - 初始化为空CLOB
            EMPTY_CLOB()
          )
       返回
          - 返回LOB定位器
          mylob INTO:mylob_loc“;

$ stmt = oci_parse($ conn,$ sql);

//创建一个“空”OCI-Lob对象以绑定到定位器
$ myLOB = oci_new_descriptor($ conn,OCI_D_LOB);

//将返回的Oracle LOB定位符绑定到PHP LOB对象
oci_bind_by_name($ stmt,“:mylob_loc”,$ myLOB,-1,OCI_B_CLOB);

//使用OCI_DEFAULT作为事务执行语句
oci_execute($ stmt,OCI_DEFAULT)
    或死亡(“无法执行查询\ n”);
    
//现在保存一个值到LOB
if(!$ myLOB-> save('INSERT:'.date('H:i:s',time()))){
    
    //出错时,回滚事务
    oci_rollback($ conn);
    
} else {

    //成功后,提交事务
    oci_commit($ conn);
    
}}

//免费资源
oci_free_statement($ stmt);
$ myLOB-> free();


//断开与DB的连接等。
?>

请注意这个例子中如何使用事务,指示 oci_execute与 OCI_DEFAULT常量等待 oci_commit或 oci_rollback。这一点很重要,因为我有两个阶段发生在 INSERT -首先创建行和第二次更新的LOB。需要注意的是,如果我是用BLOB类型,唯一需要的变化(假设BLOB列)的工作是对 oci_bind_by_name调用:

oci_bind_by_name($ stmt,“:mylob_loc”,$ myLOB,-1,OCI_B_BLOB);

或者,您可以直接绑定字符串,而不指定LOB类型;

<?php
//等等。

$ sql =“INSERT INTO
          mylobs
          ((
            ID,
            mylob
          )
        值
          ((
            mylobs_id_seq.NEXTVAL,
            :串
          )
“;

$ stmt = oci_parse($ conn,$ sql);


oci_bind_by_name($ stmt,':string',$ string);

oci_execute($ stmt)
    或死亡(“无法执行查询\ n”);

//等等。
?>

这种方法大大简化了代码,适合当你想要写入到LOB的数据相对较小。相反,如果你想大文件的内容流成LOB,你可以通过文件的内容循环调用 write()方法和 冲洗()的PHP LOB对象写较小的块上,而不是整个文件在单个实例中保持在内存中。选择LOB

当 SELECT查询包含一个LOB列,PHP将自动绑定列到OCI-LOB对象。例如:

<?php
//等等。

$ sql =“SELECT
          *:
        从
          mylobs
        ORDER BY
          ID
“;

$ stmt = oci_parse($ conn,$ sql);

oci_execute($ stmt)
    或死亡(“无法执行查询\ n”);

while($ row = oci_fetch_assoc($ stmt)){
    print“ID:{$ row ['ID']},”;
    
    //调用load()方法来获取LOB的内容
    print $ row ['MYLOB']  - > load()。“\ n”;
}}

//等等。
?>

这可以通过使用进一步简化 OCI_RETURN_LOBS恒定,与所用 oci_fetch_array() ,指示它替换为它们的值LOB对象:

while($ row = oci_fetch_array($ stmt,OCI_ASSOC + OCI_RETURN_LOBS)){
    print“ID:{$ row ['ID']},{$ row ['MYLOB']} \ n”;
}}

更新LOB要 UPDATE一个LOB,它也可以使用 “回归”中的SQL命令,与上面 的INSERT的例子,但一个更简单的方法是 SELECT ... FOR UPDATE

<?php
//等等。

$ sql =“SELECT
           mylob
        从
           mylobs
        哪里
           id = 3
        FOR UPDATE / *锁定行* /
“;

$ stmt = oci_parse($ conn,$ sql);

//使用OCI_DEFAULT执行语句(开始事务)
oci_execute($ stmt,OCI_DEFAULT) 
    或死亡(“无法执行查询\ n”);

//获取SELECTed行
if(FALSE ===($ row = oci_fetch_assoc($ stmt))){
    oci_rollback($ conn);
    die(“无法获取行\ n”);
}}

//丢弃现有的LOB内容
if(!$ row ['MYLOB']  - > truncate()){
    oci_rollback($ conn);
    die(“Failed to truncate LOB \ n”);
}}

//现在保存一个值到LOB
if(!$ row ['MYLOB']  - > save('UPDATE:'.date('H:i:s',time()))){
    
    //出错时,回滚事务
    oci_rollback($ conn);
    
} else {

    //成功后,提交事务
    oci_commit($ conn);
    
}}

//免费资源
oci_free_statement($ stmt);
$ row ['MYLOB']  - > free();


//等等。
?>

如同 INSERT,我需要执行 UPDATE使用事务。一个重要的附加步骤是将呼叫 截断() 。当更新与一个LOB 保存() ,将取代的LOB的从启动开始新的数据的长度的内容。这意味着较旧的内容(如果它比新的内容更长)可能仍然留在LOB中。对于PHP 4.x中,在 截断()是不可用的,下面的替代解决方案使用Oracle的 EMPTY_CLOB()函数的新数据保存到前擦除在LOB任何现有内容。

$ sql =“UPDATE
           mylobs
        组
            mylob = EMPTY_CLOB()
        哪里
           id = 2403
        返回
            mylob INTO:mylob
“;

$ stmt = OCIParse($ conn,$ sql);

$ mylob = OCINewDescriptor($ conn,OCI_D_LOB);

OCIBindByName($ stmt,':mylob',$ mylob,-1,OCI_B_CLOB);

//使用OCI_DEFAULT执行语句(开始事务)
OCIExecute($ stmt,OCI_DEFAULT) 
    或死亡(“无法执行查询\ n”);
    
if(!$ mylob-> save('UPDATE:'.date('H:i:s',time()))){
    
    OCIRollback($ conn);
    die(“无法更新lob \ n”);
    
}}

OCICommit($ conn);
$ mylob-> free();
OCIFreeStatement($ stmt);

使用BFILES当使用BFILE类型, INSERT S和 UPDATE刻薄告诉甲骨文在该文件所在的数据库服务器(可能不是同一台机器作为Web服务器)的文件系统中,而不是传递文件内容。使用 SELECT语句,您可以通过Oracle读取BFILE的内容,应该你愿意的话,或致电函数和过程从DBMS_LOB包,以获取有关文件的信息。

BFILE的主要优点是能够直接从文件系统访问原始文件,同时仍然能够使用SQL查找文件。这意味着,例如,图像可以直接由Web服务器提供,而我可以跟踪包含BFILES的表格和“用户”表之间的关系,告诉我谁上传了文件。

例如,我首先需要更新上面使用的表模式;

ALTER TABLE mylobs ADD(mybfile BFILE)

接下来,我需要向Oracle注册目录别名(这需要管理权限),并授予读取它的权限:

CREATE DIRECTORY IMAGES_DIR AS'/ home / harryf / public_html / images'

我现在可以 INSERT像一些BFILE的名称:

<?php
//等等。

//为BFILE名称构建一个INSERT
$ sql =“INSERT INTO
        mylobs
          ((
            ID,
            mybfile
          )
       值
          ((
            mylobs_id_seq.NEXTVAL,
            / *
            使用Oracle目录引用传递文件名
            我创建了名为IMAGES_DIR
            * /
            BFILENAME('IMAGES_DIR',:filename)
          )“;

$ stmt = oci_parse($ conn,$ sql);

//打开目录
$ dir ='/ home / harryf / public_html / images';
$ dh = opendir($ dir)
    或死亡(“无法打开$ dir”);

//循环遍历目录的内容
while(false!==($ entry = readdir($ dh))){
    
    //仅匹配扩展名为.jpg,.gif或.png的文件
    if(is_file($ dir。'/'。$ entry)&& preg_match('/ \。(jpg | gif | png)$ /',$ entry)
        
        //绑定语句的文件名
        oci_bind_by_name($ stmt,“:filename”,$ entry);
        
        //执行语句
        if(oci_execute($ stmt)){
            print“$ entry added \ n”;
        }}        
    }}
    
}}

如果我需要,我可以通过Oracle读取BFILE内容使用与上面相同的方法,我选择CLOB。或者,如果我需要获得文件名后面,所以我可以从文件系统中直接访问它们,我可以调用 DBMS_LOB.FILEGETNAME程序,如:

<?php
//等等。

$ sql =“SELECT
          ID
        从
          mylobs
        哪里
          - 只选择不为空的BFILES
          mybfile IS NOT NULL;

$ stmt1 = oci_parse($ conn,$ sql);

oci_execute($ stmt1)
    或死亡(“无法执行查询\ n”);

$ sql =“DECLARE
          定位器BFILE;
          diralias VARCHAR2(30);
          filename VARCHAR2(30);
           
        开始
          
          选择
            mybfile INTO locator
          从
            mylobs
          哪里
            id =:id;
          
          - 从BFILE获取文件名
          DBMS_LOB.FILEGETNAME(locator,diralias,filename);
          
          - 分配OUT参数以绑定参数
          :diralias:= diralias;
          :filename:= filename;
          
       结束;”;

$ stmt2 = oci_parse($ conn,$ sql);

    
    oci_bind_by_name($ stmt2,“:id”,$ row ['ID']);
    oci_bind_by_name($ stmt2,“:diralias”,$ diralias,30);
    oci_bind_by_name($ stmt2,“:filename”,$ filename,30);
    
    oci_execute($ stmt2);
    print“{$ row ['ID']}:$ diralias / $ filename \ n”;
    
}}
//等等。
?>

此外,还可以使用 DBMS_LOB.FILEEXISTS功能来发现哪些文件已通过操作系统被删除,但在数据库中仍引用。结论

在此方法文档中,你已经被介绍给不同类型的Oracle数据库10个可用的LOB ,希望现在了解他们在允许大型数据实体高效地存储在数据库中的作用。您还学习了如何使用PHP的OCI8 API来处理LOB,涵盖了在使用Oracle和PHP开发时遇到的常见用例。

 


哈利Fuecks [ http://www.phppatterns.com ]是一个知名的PHP开发人员和作家,自1999年发现PHP他发表了许多介绍,并通过中间PHP文章 Sitepoint网站开发者的网络,以及写作 的PHP文集(SitePoint)。

原文地址:http://www.oracle.com/technetwork/articles/fuecks-lobs-095315.html

Oracle中如何获取系统当前时间 - CSDN博客

mikel阅读(934)

 

来源: Oracle中如何获取系统当前时间 – CSDN博客

Oracle中如何获取系统当前时间
select to_char(sysdate,’yyyy-mm-dd hh24:mi:ss’) from dual;
ORACLE里获取一个时间的年、季、月、周、日的函数
select  to_char(sysdate, ‘yyyy’ )  from dual; –年
select  to_char(sysdate, ‘MM’ )  from dual; –月
select  to_char(sysdate, ‘dd’ )  from dual; –日
select  to_char(sysdate, ‘Q’)  from dual; –季
select  to_char(sysdate, ‘iw’)  from dual; –周–按日历上的那种,每年有52或者53周
/*
hh 小时(12)
hh24 小时(24)
Mi 分
ss 秒
D 周中的星期几
ddd 年中的第几天
WW 年中的第几个星期
W 该月中第几个星期 –每年的1月1号至1月7号为第一周,以此类推,每年53周
*/
获取系统日期: SYSDATE()
  格式化日期:
     TO_CHAR(SYSDATE(),’YY/MM/DD HH24:MI:SS)
    或 TO_DATE(SYSDATE(),’YY/MM/DD HH24:MI:SS)
   select to_char(sysdate,’yyyy-MM-dd HH24:mi:ss’)  from dual;
   select to_char(sysdate,’yyyy-MM-dd HH24:mm:ss’)  from dual;
   select to_char(sysdate,’yy-mm-dd hh24:mi:ss’)  from dual
   select to_date(‘2009-12-25 14:23:31′,’yyyy-mm-dd,hh24:mi:ss’) from dual
  而如果把上式写作:
   select  to_date(‘2009-12-25 14:23:31′,’yyyy-mm-dd,hh:mi:ss’)  from dual
  则会报错,因为小时hh是12进制,14为非法输入,不能匹配。
  转换的格式:
  表示 year 的:
    y 表示年的最后一位 、
  yy 表示年的最后2位 、
  yyy 表示年的最后3位 、
  yyyy 用4位数表示年
  表示month的:
    mm 用2位数字表示月 、
  mon 用简写形式, 比如11月或者nov 、
  month 用全称, 比如11月或者november
  表示day的:
    dd 表示当月第几天 、
  ddd 表示当年第几天 、
  dy 当周第几天,简写, 比如星期五或者fri 、
  day 当周第几天,全称, 比如星期五或者friday
  表示hour的:
    hh 2位数表示小时 12进制 、
  hh24 2位数表示小时 24小时
  表示minute的:
    mi 2位数表示分钟
  表示second的:
    ss 2位数表示秒 60进制
  表示季度的:
    q 一位数 表示季度 (1-4)
  另外还有ww 用来表示当年第几周 w用来表示当月第几周。
  当前时间减去7分钟的时间
   select   sysdate,sysdate – interval ‘7’ MINUTE  from  dual;
  当前时间减去7小时的时间
   select   sysdate – interval ‘7’ hour  from dual;
  当前时间减去7天的时间
   select   sysdate – interval ‘7’ day  from dual;
  当前时间减去7月的时间
   select   sysdate,sysdate – interval ‘7’ month  from dual;
  当前时间减去7年的时间
   select   sysdate,sysdate – interval ‘7’ year  from dual;
  时间间隔乘以一个数字
   select   sysdate,sysdate – 8*interval ‘7’ hour  from dual;
    select to_char(sysdate,’yyyy-mm-dd:hh24:mi:ss:pm:dy’) from dual;                     年  月 日 24制小时 分 秒 上/下午 星期中文;
–获取11月天数–select to_char(last_day(to_date(‘2010-11-1′,’YYYY-MM-DD’)),’DD’) from dual;
–获取12月天数–select to_char(last_day(to_date(‘2010-12-1′,’YYYY-MM-DD’)),’DD’) from dual;
显示上个礼拜一到礼拜日  SELECT to_char(SYSDATE,’yyyymmdd’)-to_number(to_char(SYSDATE,’d’)-1) – 6, to_char(SYSDATE,’yyyymmdd’)-to_number(to_char(SYSDATE,’d’)-1)    from dual

转自:http://www.2cto.com/database/201304/202675.html

创业者必读:创业失败有20个主要原因,你自我检查了吗?_36氪

mikel阅读(839)

出于兴趣而不是市场需求去解决一个问题,这是失败的第一大原因。

来源: 创业者必读:创业失败有20个主要原因,你自我检查了吗?_36氪

编者按:CB Insights曾经对101家失败的创业公司进行分析,找到20个主要败因。现在它又举出案例,对20个败因进行分析。让我们来学习一下。

我们分析了101家走向失败的创业公司,从中总结出20个主要败因,有的因为产品市场不匹配而失败,有的因为团队糟糕而失败。

当我们汇总失败创业公司的名单时,有许多人提出请求,希望我们能分析一下。

创业公司、企业、投资人、经济发展相关人士、学者、记者都想深入了解一个问题:

创业公司因为什么原因失败?

CB Insights对数据进行处理,看看能否找到答案。

创业者必读:创业失败有20个主要原因,你自我检查了吗?

查看101家公司的“死亡报告”之后,我们发现很少有企业因为一个原因失败。尽管如此,从这些失败故事中我们还是可以找到一些模式的:

整理之后,我们列出20个导致创业公司失败的最大原因。

因为有许多创业公司因为多种多样原因失败,你会发现,将表格中20个原因的比例加起来,数字远超100%。

在图表下面,我们会对每一个原因进行解释,列出相关案例供您参考。

请注意,如果没有大量创始人分享自己的失败故事,我们不可能有数据来分析。感谢他们。

第20位:未能及时调整方向

在“死亡报告”中,因为出现坏产品、招人失败或者决策失误,企业没有摆脱影响,或者摆脱的速度不够快,结果走向死亡,这个原因占了7%。糟糕的创意会消耗资源和金钱,业务迟迟没有进展,员工会感到沮丧。

创业者必读:创业失败有20个主要原因,你自我检查了吗?

Keith Nowak在分析Imercive的“死亡报告”中说:“我们陷入‘mid-pivot’无法自拔:也就是说有一个战略我们知道不管用,还有一个战略我们相信会成功,但是我们陷入二者之间,不能积极推行新战略。此时处境很尴尬,无论从专业角度还是从个人角度看,都相当困难。因为未能追求新战略,我们感到极为沮丧,没有有意义的进步意味着我的第一家公司每一天都在朝着失败靠近。我们曾经竭尽全力,想度过这一困难期,可惜还是没有做到。”

第19位:筋疲力尽

创业者必读:创业失败有20个主要原因,你自我检查了吗?

保持“工作-生活“的平衡相当重要,许多创业公司创始人没有做到,于是筋疲力尽的概率就会很高。在失败报告中,有8%的案例将疲累作为原因。当你发现企业走进死胡同时,必须在必要的地方减少损失,重新定向,这点很重要;拥有一个强大的团队(有凝聚力、多样化、积极进取的团队)同样重要,大家可以分担责任,提高成功的概率,这两点都不能忽视。

第18位:没有利用好人脉网络

我们经常听到创业公司企业家抱怨说,他们没有强大的人脉网络,与投资人关系不好;在失败案例中,我们听到一个让人惊讶的原因:企业家说他们未能利用好自己的网络。

创业者必读:创业失败有20个主要原因,你自我检查了吗?

Kiko是这样说的:“让你的投资人参与进来。投资人是来帮你的,让他们从一开始就参与,多向他们寻求帮忙,不要害怕。我想我们在早期犯了错,一切都亲力亲为,可能是因为刚刚进入商业世界,没有安全感吧。这是一个错误。”

第17位:法务挑战

有时,一家创业公司从简单的创意起步,渐渐卷入复杂的法务世界,结果这种复杂性成为企业的主要死因。

Decide.com对自己的失败是这样剖析的:

创业者必读:创业失败有20个主要原因,你自我检查了吗?

“我们收到它们的一份通知,说我们不合规,除非我们解决,否则就会封禁我们的附属帐号。我们并没有赚到多少钱,不过这个帐号占了我们营收的80%以上。”

对一些失败音乐创业公司进行分析会发现,与唱片公司打交道、处理法律事务成本很高,它成为创业公司失败的一个主要原因。

曾经红极一时的创业公司Turntable.fm是这样说的:

“有许多音乐创业公司失败,我未能汲取教训。有代价昂贵的风险要你去冒,与你打交道的行业相当棘手。我们的现金超过四分之一用来支付律师费、版费以及与音乐支持有关的服务费。我们不得不放慢增长速度,因为我们无法在进入国际市场。”

第16位:没有投资者感兴趣

创业者必读:创业失败有20个主要原因,你自我检查了吗?

许多创业公司创始人说,在种子阶段之后(Series A)投资人没兴趣继续投资,或者根本没有兴趣,这是公司失败的主要原因,而投资人没兴趣往往又与缺少现金这个原因息息相关。

第15位:地理位置安排不当

位置是一个重要问题,而问题的形式又是多种多样的。例如,创业公司的概念与位置是否一致就很重要。

创业者必读:创业失败有20个主要原因,你自我检查了吗?

听听Meetro的说法:

“我们推出产品,让所有的芝加哥朋友都来买。当时地区最大的报纸刊文详细报道我们,一切看起来很好……很快我们就发现,虽然我们在芝加哥有几百名活跃用户,但它并不意味着我们可以在Milwaukee轻松获得2名活跃用户,而Milwaukee离芝加哥只有一百英里远,更不必说纽约或者旧金山了。软件和概念没有那么简单就能跨越物理边界。”

对于远程团队来说,位置往往是失败的一个重要原因。如果你的团队远程办公,你必须找到有效的沟通手段,否则团队工作就会缺少协作、缺少规划,最终成为失败的诱因。

正如Devver所说的:

“远程团队有一个最明显的缺点:管理混乱。即使只是小团队,在一个州管理好工资单、失业、保险等事务,也是一件头痛的事,很烦,很让人分心。”

第14位:缺少激情

世界上从不缺少好创意,但是在创业“死亡报告”中,有9%提到一个原因:对某个领域缺少激情,或者缺少某个领域的知识,这才是失败的关键原因,而不是因为你没有好创意。

创业者必读:创业失败有20个主要原因,你自我检查了吗?

在报告中,NewsTilt坦白承认说他们对自己挑选的领域缺少激情,NewsTilt是这样说的:

“公正地说,我们对于新闻行业缺少真正的兴趣。我最开始时之所以开发评论产品,只是因为我想为自己的博客找一个完美的评论系统。后来我开始设计出色的评论系统,而系统的理想客户是报纸。”

“不过我们对新闻行业并不感兴趣,我们甚至都不是热情的新闻读者。如果每天我做的第一件事是访问news.bbc.co.uk,我们就应该开发这样的产品。即使我们开发了NewsTilt,它也不是我必去的地方,我必去的地方是Hacker News和Reddit。如果我们对一件事情感兴趣纯粹只是出于商业原因,又怎么能开发好产品呢?”

第13位:转型失利

Burbn变成了Instagram,ThePoint变成了Groupon,如果能像它们一样成功就好了,否则你会走上不归路。

创业者必读:创业失败有20个主要原因,你自我检查了吗?

Flowtab对于自己的失败是这样解释的:“为了转型而转型是没有意义的。必须好好规划,知道要对商业模式做怎样的调整,对假设进行测试,对结果进行评估。否则你什么东西也学不到。”

第12位:团队与投资人不和

在创业公司失败报告中,联合创始人内讧是一个致命原因。不过不和并不限于创始团队,如果与投资人闹翻了,失败很快就会降临,ArsDigital就是一个好例子。

Phillip Greenspun是这样说的:

创业者必读:创业失败有20个主要原因,你自我检查了吗?

“在大约一年的时间里,Peter Bloom (General Atlantic,泛大西洋资本集团)、Chip Hazard (Greylock,创投公司格雷洛克)和Allen Shaheen (CEO)对ArsDigita行使绝对权力。在这一年里,他们做了如下一些事:

——花了2000万美元让公司营收回到我当CEO时的水平。

——微软2000年夏天开价收购公司,ArsDigita有机会成为第一大a .NET企业软件公司,他们拒绝了。

——在新产品(ACS 4.x)完成之前废弃完整的老产品(ACS 3.4)。

——成本架构极高:我当时主管公司时只有80人,大部分人的基本薪酬不到10万美元,年营收达到2000万美元。Greylock、General Atlantic和Allen掌管的ArsDigita却有近200名员工,设了许多新管理职位,年薪达到20万美元甚至更高。

——市场领导力(market leadership)和思想领导力( thought leadership)下降。

第11位:偏离中心

在失败故事中,有13%了分心问题:被无关紧要的项目、个人事物或者(和)综合性的焦点偏离所困扰。

MyFavorites在失败之后分析说:

创业者必读:创业失败有20个主要原因,你自我检查了吗?

“当我们从SXSW回来后,我们全都开始失去兴趣,团队全都想知道公司最终走向何处,我自己也在想我是不是真的想运营一家创业公司,是不是想引入投资者,是不是想承担员工责任,应付投资者。”

第10位:产品时机不对

如果产品发布过早,用户可能会说它不够好,到时再想让用户回来就很难了,因为你给他们的第一印象不好。如果你发布产品太迟,就会错过市场机会。

Calxeda的员工是这样说的:

创业者必读:创业失败有20个主要原因,你自我检查了吗?

“以Calxeda为例,我们前进的速度太快,客户追不上。我们提供的技术不是他们想要的,例如,我们用的是32位,他们却要64位。当操作系统生态环境还在充实时,我们已经行动了:现在Canonical(Ubuntu Linux的开发商)发展很好,红帽呢,去哪里了?我们进入太早了。”

第9位:忽视客户

忽视用户往往会导致失败。视野狭窄,没有收集用户反馈意见,这是许多创业公司失败的主要原因。

例如eCrowds就是这样失败的,它是一家内容管理系统公司。

创业者必读:创业失败有20个主要原因,你自我检查了吗?

eCrowds剖析说:

“我们花了太多时间完善自我,却没有收集前景反馈意见,这样很容易导致视野狭窄。我建议大家从一开始就要收集前景反馈意见,不要等上2个月或者3个月,意见必须客观。”

VoterTide也是这样说的:

“我们没有花足够的时间与客户对话,我们埋头推出自己认为好的功能,但是没有从客户那里收集充分的意见,意识到时已经晚了。你很容易就会陷进去,认为自己的东西很酷。你必须留意自己的客户,根据他们的需求调整。”

第8位:营销不到位

知道你的目标客户在哪里,知道如何引起他们的注意,将它们转化为领导客户和终极客户,这是走向成功的关键。营销不利是企业失败的主要原因之一,许多创始人只喜欢编写代码,开发产品,不会推广产品。

创业者必读:创业失败有20个主要原因,你自我检查了吗?

听听Overto的说法:

“用户数量决定互联网服务的生与死。在最初的日子,数字增长是系统性的。然后触及天花板,此时做事就会轻松很多,是时候做一些营销了。很遗憾,我们之中没有谁擅长营销。更糟糕的是,没有谁有足够的时间来弥补缺失。如果当时我们动手解决上面所说的问题时,缺少相应人才可能是另一个障碍。”

第7位:有产品没有商业模式

商业模式很重要,失败的创业者似乎都表示认同,他们执著于单一渠道,或者找不到大规模赚钱的方法,最终让投资者犹豫不定,创始人无法利用好形势。

创业者必读:创业失败有20个主要原因,你自我检查了吗?

Tutorspree是这样说的:

“虽然Tutorspree取得许多成功,但是我们未能打造一项成规模的业务……Tutorspree之所以不能形成规模,主要是因为我们依赖单一渠道,渠道的变化会给公司带来动荡。从一开始,我们就将SEO放入模式,当我们渐渐壮大,它变得越来越重要。在发展早期,在Y Combinator阶段,我们没有钱收购。SEO是免费的,我们专注SEO,而且很擅长。”

第6位:产品对用户不友好

用户想要什么?需要什么?如果你忽视,不论是有意还是无意,都是一件糟糕的事。

创业者必读:创业失败有20个主要原因,你自我检查了吗?

听听GameLayers是怎么说自己的产品UI的:

“最终我相信PMOG缺少核心游戏冲动,无法让大众热爱。我们‘留下一些好玩的网页注解’,这个概念让玩家们感到困惑。回看过去,我相信我们应该好好清除障碍,收起骄傲,开发一些容易上手又好玩的东西,让用户从一开始时就能轻松玩。”

第5位:价格/成本问题

对于创业公司来说,定价是一种“黑暗艺术”,分析创业公司死亡报告 ,会发现定价是一件很难的事,价格必须高到可以收回成本,又必须低到可以吸引客户。

创业者必读:创业失败有20个主要原因,你自我检查了吗?

Delight IO认为定价很难。注册使用Delight.io的开发者可免费获得50次用户使用情况的视频录制,之后就需付费了,50美元20次视频录制,100美元50次视频录制。后来改变规则。听听它是怎样说的:

“我们最贵的月套餐是300美元。客户从没有抱怨过价格,我们只是没有达到他们的预期。最开始时,我们根据记录积分的数量定价。因为客户无法控制记录的长度,所以使用积分时会很谨慎。后来我们根据录制的累计持续时间来计费,这样就好多了,订阅者也多了起来。”

第4位:被淘汰出局

许多人说创业公司不应该关注竞争,现实却告诉我们,一旦某个概念热起来,在市场上得到验证,就会有许多复制者跑出来。过度关注竞争是不健康的,但是忽视竞争也是失败的诱因,19%的失败创业公司都将它列出来。

创业者必读:创业失败有20个主要原因,你自我检查了吗?

Wesabe的Mark Hedland曾经谈到自己的失败:

“Wesabe收集的数据更糟糕,工作量大得多,相比而言,Mint的体验好很多,良好的体验来自于快得多的速度。不要依赖单一源,要尊重用户隐私,真正在财务方面帮助用户,这些都很重要,也是我们应该追求的。不过如果产品很难使用,一切都是白搭。”

第3位:团队不行

企业如果想成功,组建多样化团队,拥有多种多样的技能,这点很重要。分析“死亡报告”,经常听到有人说:“真希望从一开始就能有一名CTO。”或者说创业公司“应该有一位热爱业务各方面的创始人。”。

创业者必读:创业失败有20个主要原因,你自我检查了吗?

Standout Jobs在”死亡报告”中是这样解释的:

“创始团队不可能自己创造一名MVP,这样做是错的。如果创始团队不能自己开发出产品(或者从自由职业者那里获得一定的帮助),那就不应该成立公司。我们应该引入联合创始人,主要用股票补偿他们,不是现金,可惜我们没有这样做。”

在某些案例中,创始团队希望他们能有更多的制衡。Nouncer的创始人是这样说的:“我们没有一位可以制衡我的合伙人,他可以对业务和技术决策的合理性进行检查。”

第2位:缺少现金

资金与时间是有限的,必须合理分配。如何花钱是一个难题,有29%的企业因此死亡。

创业者必读:创业失败有20个主要原因,你自我检查了吗?

以Flud团队为例,现金耗光往往与其它原因有关,比如没有找到与市场匹配的产品,没有正确转型。

“事实上,最终杀死Flud的原因在于公司无法融入更多资金。虽然我们想尽办法,试图化解深奥难懂的‘产品市场匹配’问题,可惜Flud还是耗光了现金,运营持续不下去了。”

第1位:市场不需要

出于兴趣而不是市场需求去解决一个问题,这是失败的第一大原因,在所说案例中有42%提到了。

创业者必读:创业失败有20个主要原因,你自我检查了吗?

Patient Communicator是这样说的:

“我意识到,我们之所以没有客户,是因为没有人对我们所说的模式感兴趣。医生需要的是更多病人,不是高效办公室。”

Treehouse Logic对此有着更深的阐述:

当创业公司没有解决市场需要解决的问题时,就会失败。我们解决的问题不够大,没有用一套伸缩的解决方案解决大问题。我们的确有很好的技术,有不错的购物行为数据,还有很好的声誉,相当于领袖、专家与顾问,但是我们缺少一样东西:没有一套技术或者商业模式以可伸缩的方式解决难题。

编译组出品。