<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="wordpress/2.2" -->
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	>

<channel>
	<title>程序员实验室</title>
	<link>http://www.prglab.com/blog</link>
	<description>多读书，读好书</description>
	<pubDate>Tue, 05 Aug 2008 15:46:04 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.2</generator>
	<language>en</language>
			<item>
		<title>[JAVA]怎样验证XML文件是否符合schema定义</title>
		<link>http://www.prglab.com/blog/p/78</link>
		<comments>http://www.prglab.com/blog/p/78#comments</comments>
		<pubDate>Mon, 05 May 2008 18:21:34 +0000</pubDate>
		<dc:creator>Aqua</dc:creator>
		
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://www.prglab.com/blog/p/78</guid>
		<description><![CDATA[两种方法：
1。 使用SAX解析：

/***
* @param xmlPath - XML文件路径
* @param schemaPath - Schema文件路径
*/
public void saxValidation(String xmlPath, String schemaPath){
try {
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
saxParserFactory.setNamespaceAware(true);
saxParserFactory.setValidating(true);
SAXParser saxParser = saxParserFactory.newSAXParser();
saxParser.setProperty(&#34;http://java.sun.com/xml/jaxp/properties/schemaLanguage&#34;, &#34;http://www.w3.org/2001/XMLSchema&#34;);
saxParser.setProperty(&#34;http://java.sun.com/xml/jaxp/properties/schemaSource&#34;, schemaPath);
DefaultHandler handler = new DefaultHandler();
saxParser.parse(xmlPath, handler);
} catch(SAXException exc) {
exc.printStackTrace();
}
}

2。 使用DOM解析：

/***
* @param xmlPath - XML文件路径
* @param schemaPath - Schema文件路径
*/
public void domValidation(String xmlPath, String schemaPath){
try {
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
docBuilderFactory.setNamespaceAware(true);
docBuilderFactory.setValidating(true);
docBuilderFactory.setAttribute(&#34;http://java.sun.com/xml/jaxp/properties/schemaLanguage&#34;, &#34;http://www.w3.org/2001/XMLSchema&#34;);
docBuilderFactory.setAttribute(&#34;http://java.sun.com/xml/jaxp/properties/schemaSource&#34;, schemaPath);
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
Document [...]]]></description>
			<content:encoded><![CDATA[<p>两种方法：</p>
<p>1。 使用SAX解析：</p>
<pre class="syntax-highlight:java">
/***
* @param xmlPath - XML文件路径
* @param schemaPath - Schema文件路径
*/
public void saxValidation(String xmlPath, String schemaPath){
try {
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
saxParserFactory.setNamespaceAware(true);
saxParserFactory.setValidating(true);
SAXParser saxParser = saxParserFactory.newSAXParser();
saxParser.setProperty(&quot;http://java.sun.com/xml/jaxp/properties/schemaLanguage&quot;, &quot;http://www.w3.org/2001/XMLSchema&quot;);
saxParser.setProperty(&quot;http://java.sun.com/xml/jaxp/properties/schemaSource&quot;, schemaPath);
DefaultHandler handler = new DefaultHandler();
saxParser.parse(xmlPath, handler);
} catch(SAXException exc) {
exc.printStackTrace();
}
}
</pre>
<p>2。 使用DOM解析：</p>
<pre class="syntax-highlight:java">
/***
* @param xmlPath - XML文件路径
* @param schemaPath - Schema文件路径
*/
public void domValidation(String xmlPath, String schemaPath){
try {
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
docBuilderFactory.setNamespaceAware(true);
docBuilderFactory.setValidating(true);
docBuilderFactory.setAttribute(&quot;http://java.sun.com/xml/jaxp/properties/schemaLanguage&quot;, &quot;http://www.w3.org/2001/XMLSchema&quot;);
docBuilderFactory.setAttribute(&quot;http://java.sun.com/xml/jaxp/properties/schemaSource&quot;, schemaPath);
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
Document doc = docBuilder.parse(xmlPath);
} catch(DOMException exc) {
exc.printStackTrace();
}
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.prglab.com/blog/p/78/feed</wfw:commentRss>
		</item>
		<item>
		<title>使用JAVA将彩色图片变为1bit黑白图片</title>
		<link>http://www.prglab.com/blog/p/73</link>
		<comments>http://www.prglab.com/blog/p/73#comments</comments>
		<pubDate>Thu, 01 May 2008 21:05:31 +0000</pubDate>
		<dc:creator>Aqua</dc:creator>
		
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://www.prglab.com/blog/p/73</guid>
		<description><![CDATA[最近做的project需要涉及到对扫描图片的文字识别，需要将扫描得到的彩色图片变为1bit的黑白图片。
搜索到很多解决方案，基本的归纳为两个步骤，首先要将彩色图片变为8bit灰度图片(grayscale image)，然后再进一步变为1bit的单色图片(1bit monochrome)。
使用ColorConvert和Dithering操作
代码
目前JAVA最新的图片处理包应该是JAI(Java Advanced Imaging)，在JAI API的FAQ页面上，找到了下面的方法来完成这两步工作：


将彩色图片转换为8bit灰度图片(使用ColorConvert颜色转换操作)




public RenderedImage convertTo8BitGray(RenderedImage colorImage){
ParameterBlock pb = new ParameterBlock();
pb.addSource(colorImage);
ColorModel cm = new ComponentColorModel(
ColorSpace.getInstance(ColorSpace.CS_GRAY),
new int[]{8},
false,
false,
Transparency.OPAQUE,
DataBuffer.TYPE_BYTE);
pb.add(cm);
RenderedImage grayImage = JAI.create(&#34;ColorConvert&#34;, pb);
return grayImage;
}





将8bit灰度图片转换为1bit黑白图片 (使用errordiffusion或ordereddither操作)




public  RenderedImage applyDithering(RenderedImage grayImage, boolean isErrorDiffusion){
// Load the ParameterBlock for the dithering operation
// and set the operation name.
ParameterBlock pb = new ParameterBlock();
pb.addSource(grayImage);
String opName = null;
if(isErrorDiffusion) {
opName = &#34;errordiffusion&#34;;
LookupTableJAI lut = new [...]]]></description>
			<content:encoded><![CDATA[<p>最近做的project需要涉及到对扫描图片的文字识别，需要将扫描得到的彩色图片变为1bit的黑白图片。</p>
<p>搜索到很多解决方案，基本的归纳为两个步骤，首先要将彩色图片变为8bit灰度图片(grayscale image)，然后再进一步变为1bit的单色图片(1bit monochrome)。</p>
<h3>使用ColorConvert和Dithering操作</h3>
<h4>代码</h4>
<p>目前JAVA最新的图片处理包应该是JAI(Java Advanced Imaging)，在<a href="http://http://java.sun.com/products/java-media/jai/forDevelopers/jaifaq.html#1bit" target="_blank">JAI API的FAQ页面</a>上，找到了下面的方法来完成这两步工作：</p>
<table style="border-color: #aaaaaa; border-width: 1px" border="0" height="237" width="566">
<tr>
<td style="border: 1px solid #cccccc; background-color: #eeeeee">将彩色图片转换为8bit灰度图片(使用ColorConvert颜色转换操作)</td>
</tr>
<tr>
<td style="border: 1px solid #cccccc">
<pre class="syntax-highlight:java">
public RenderedImage convertTo8BitGray(RenderedImage colorImage){
ParameterBlock pb = new ParameterBlock();
pb.addSource(colorImage);
ColorModel cm = new ComponentColorModel(
ColorSpace.getInstance(ColorSpace.CS_GRAY),
new int[]{8},
false,
false,
Transparency.OPAQUE,
DataBuffer.TYPE_BYTE);
pb.add(cm);
RenderedImage grayImage = JAI.create(&quot;ColorConvert&quot;, pb);
return grayImage;
}</pre>
</td>
</tr>
</table>
<table style="border-color: #aaaaaa; border-width: 1px" border="0" height="40" width="566">
<tr>
<td style="border: 1px solid #cccccc; background-color: #eeeeee">将8bit灰度图片转换为1bit黑白图片 (使用errordiffusion或ordereddither操作)</td>
</tr>
<tr>
<td style="border: 1px solid #cccccc">
<pre class="syntax-highlight:java">
public  RenderedImage applyDithering(RenderedImage grayImage, boolean isErrorDiffusion){
// Load the ParameterBlock for the dithering operation
// and set the operation name.
ParameterBlock pb = new ParameterBlock();
pb.addSource(grayImage);
String opName = null;
if(isErrorDiffusion) {
opName = &quot;errordiffusion&quot;;
LookupTableJAI lut = new LookupTableJAI(new byte[] {(byte)0x00, (byte)0xff});
pb.add(lut);
pb.add(KernelJAI.ERROR_FILTER_FLOYD_STEINBERG);
} else {
opName = &quot;ordereddither&quot;;
ColorCube cube = ColorCube.createColorCube(DataBuffer.TYPE_BYTE,
0, new int[] {2}); //尝试改变2为其它值，可以得到不同效果
pb.add(cube);
pb.add(KernelJAI.DITHER_MASK_441);
}
// Create a layout containing an IndexColorModel which maps
// zero to zero and unity to 255.
ImageLayout layout = new ImageLayout();
byte[] map = new byte[] {(byte)0x00, (byte)0xff};
ColorModel cm = new IndexColorModel(1, 2, map, map, map);
layout.setColorModel(cm);
// Create a hint containing the layout.
RenderingHints hints = new RenderingHints(JAI.KEY_IMAGE_LAYOUT, layout);
// Dither the image.
bwImage = JAI.create(opName, pb, hints);
return bwImage;
}
</pre>
</td>
</tr>
</table>
<h4>问题</h4>
<p>这段sample code在很多地方都被提到过，我不知道别人是否能够让它顺利执行，但是在我的机器上是不行的。</p>
<p>问题主要出在第一个convertTo8BitGray()函数里的ColorConvert操作上。在执行完ColorConvert之后，图片的ColorModel的numberOfComponents变为1。我的理解是因为变为灰度图片，只有一个色了。</p>
<p>然而不知为什么，图片的SampleModel的numberOfBands却仍然保持了3，这就造成了SampleModel和ColorModel 不兼容，所以程序总是抛出<font color="#ff0000">java.lang.IllegalArgumentException: The specified ColorModel is incompatible with the image SampleModel&#8230;</font>的错误。</p>
<p> <a href="http://www.prglab.com/blog/p/73#more-73" class="more-link">(more&#8230;)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.prglab.com/blog/p/73/feed</wfw:commentRss>
		</item>
		<item>
		<title>ABAP中如何检查字母数字类型(alpha numeric)的变量</title>
		<link>http://www.prglab.com/blog/p/72</link>
		<comments>http://www.prglab.com/blog/p/72#comments</comments>
		<pubDate>Sat, 12 Apr 2008 03:02:50 +0000</pubDate>
		<dc:creator>Aqua</dc:creator>
		
		<category><![CDATA[ABAP]]></category>

		<guid isPermaLink="false">http://www.prglab.com/blog/p/72</guid>
		<description><![CDATA[Business requirment经常要求某个ID的值只能包含26个字母和10个数字字符，这就要求ABAP程序能够检查相应变量内容，辨别特殊字符。sap-img上的一个例子提供了这样的功能：
REPORT ZCHECK_ALPHA_NUMERIC.
* Declare the variable
* For Length 
data: serial_length type i.
* For Alpha numeric 
data: str type string.
data: valid_characters type string.
* Fill in those valid characters you need to check 
concatenate &#8216;0123456789&#8242; &#8216;ABCDEFGHIJKLMNOPQRSTUVWXYZ&#8217;
&#8216;abcdefghijklmnopqrstuvwxyz&#8217; into valid_characters.
* User Input 
parameters testchar(10) default &#8216;12345abc&#8217;.
* Get User Input 
str = testchar.
* The Checks 
if str co valid_characters.
write: / [...]]]></description>
			<content:encoded><![CDATA[<p>Business requirment经常要求某个ID的值只能包含26个字母和10个数字字符，这就要求ABAP程序能够检查相应变量内容，辨别特殊字符。<a href="http://www.sap-img.com/abap/check-length-and-alpha-numeric-variable.htm" target="_blank">sap-img上的一个例子</a>提供了这样的功能：</p>
<p>REPORT ZCHECK_ALPHA_NUMERIC.</p>
<p><font color="#3366ff">* Declare the variable</font></p>
<p><font color="#3366ff">* For Length </font><br />
data: serial_length type i.</p>
<p><font color="#3366ff">* For Alpha numeric </font><br />
data: str type string.<br />
data: valid_characters type string.</p>
<p><font color="#3366ff">* Fill in those valid characters you need to check </font><br />
concatenate &#8216;0123456789&#8242; &#8216;ABCDEFGHIJKLMNOPQRSTUVWXYZ&#8217;<br />
&#8216;abcdefghijklmnopqrstuvwxyz&#8217; into valid_characters.</p>
<p><font color="#3366ff">* User Input </font><br />
parameters testchar(10) default &#8216;12345abc&#8217;.</p>
<p><font color="#3366ff">* Get User Input </font><br />
str = testchar.</p>
<p><font color="#3366ff">* The Checks </font><br />
if str co valid_characters.<br />
write: / str, &#8216;Characters are OK&#8217;.<br />
else.<br />
write: / str, &#8216;Characters are NOT OK&#8217;.<br />
endif.</p>
<p>*&#8211; End Program</p>
<p>基于同样的原理，下面这个subroutine可以去掉一个字符串中的所有特殊字符</p>
<p><font color="#3366ff">*&amp;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;*<br />
*&amp;      Form  convert_character_entities<br />
*&amp;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;*<br />
*  This form removes all non-alpha-numeric characters from a string<br />
*&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-*<br />
*      &lt;&#8211;<br />
*&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-*</font><br />
FORM remove_non_alpha_numeric_char.<br />
DATA: l_teststr       TYPE string,<br />
l_alpha_numeric TYPE string.<br />
DATA: l_strlen TYPE i.</p>
<p>DATA: l_char TYPE c.</p>
<p>l_teststr = &#8216;ref0 0@2$45*8&#8242;.<br />
l_strlen = strlen( l_teststr ).<br />
WRITE: / l_teststr, &#8216;length:&#8217;, l_strlen.</p>
<p>l_alpha_numeric = &#8216;0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ&#8217;.</p>
<p>WHILE l_strlen &lt;&gt; 0.<br />
l_strlen = l_strlen - 1.<br />
l_char = l_teststr+l_strlen(1).<br />
IF l_alpha_numeric NA l_char.<br />
REPLACE SECTION OFFSET l_strlen LENGTH 1 OF l_teststr WITH &#8221;.<br />
ENDIF.<br />
ENDWHILE.<br />
l_strlen = strlen( l_teststr ).<br />
WRITE: / l_teststr, &#8216;length:&#8217;, l_strlen.</p>
<p>ENDFORM.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.prglab.com/blog/p/72/feed</wfw:commentRss>
		</item>
		<item>
		<title>SAP中国家代码和国家名称对应查询</title>
		<link>http://www.prglab.com/blog/p/71</link>
		<comments>http://www.prglab.com/blog/p/71#comments</comments>
		<pubDate>Fri, 28 Mar 2008 18:17:16 +0000</pubDate>
		<dc:creator>Aqua</dc:creator>
		
		<category><![CDATA[ABAP]]></category>

		<guid isPermaLink="false">http://www.prglab.com/blog/p/71</guid>
		<description><![CDATA[SAP中的国家代码表是T005T.
另外 ADRC表的COUNTRY字段的帮助视图(Help View)，也可以看到country code 和 country name的对应表。
]]></description>
			<content:encoded><![CDATA[<p>SAP中的国家代码表是T005T.</p>
<p>另外 ADRC表的COUNTRY字段的帮助视图(Help View)，也可以看到country code 和 country name的对应表。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.prglab.com/blog/p/71/feed</wfw:commentRss>
		</item>
		<item>
		<title>ABAP字符串比较中空格的影响</title>
		<link>http://www.prglab.com/blog/p/70</link>
		<comments>http://www.prglab.com/blog/p/70#comments</comments>
		<pubDate>Wed, 26 Mar 2008 17:50:34 +0000</pubDate>
		<dc:creator>Aqua</dc:creator>
		
		<category><![CDATA[ABAP]]></category>

		<guid isPermaLink="false">http://www.prglab.com/blog/p/70</guid>
		<description><![CDATA[ABAP对字符串有很多隐形的操作，有时更方便程序员，有时又比较容易使人困惑。
比如在比较字符串的值时，ABAP会自动忽视有效字符后面的空格，而如果在字符前面有空格，则会影响比较的结果。
比如： &#8216;X&#8217; 和 &#8216;X__&#8217; 比较的结果是相等；而&#8217;X'和&#8217;__X&#8217;比较的结果则是不相等。 （这里下划线__代表空格）
运行下面的程序可以看到效果：
DATA: l_string1 TYPE string,
l_string2 TYPE string,
l_string3 TYPE string.
l_string1 = &#8216;X&#8217;. &#8220;No space
l_string2 = &#8216;X &#8216;. &#8220;Space after X
l_string3 = &#8216; X&#8217;. &#8220;Space before X
IF l_string1 EQ l_string2.
WRITE: / &#8216;String 1 and String 2 are identical.&#8217;.
ELSE.
WRITE: / &#8216;String 1 and String 2 are NOT identical.&#8217;.
ENDIF.
IF l_string1 EQ l_string3.
WRITE: / &#8216;String 1 [...]]]></description>
			<content:encoded><![CDATA[<p>ABAP对字符串有很多隐形的操作，有时更方便程序员，有时又比较容易使人困惑。</p>
<p>比如在比较字符串的值时，ABAP会自动忽视有效字符后面的空格，而如果在字符前面有空格，则会影响比较的结果。</p>
<p>比如： &#8216;X&#8217; 和 &#8216;X__&#8217; 比较的结果是相等；而&#8217;X'和&#8217;__X&#8217;比较的结果则是不相等。 （这里下划线__代表空格）</p>
<p>运行下面的程序可以看到效果：</p>
<p>DATA: l_string1 TYPE string,<br />
l_string2 TYPE string,<br />
l_string3 TYPE string.<br />
l_string1 = &#8216;X&#8217;. &#8220;No space<br />
l_string2 = &#8216;X &#8216;. &#8220;Space after X<br />
l_string3 = &#8216; X&#8217;. &#8220;Space before X<br />
IF l_string1 EQ l_string2.<br />
WRITE: / &#8216;String 1 and String 2 are identical.&#8217;.<br />
ELSE.<br />
WRITE: / &#8216;String 1 and String 2 are NOT identical.&#8217;.<br />
ENDIF.<br />
IF l_string1 EQ l_string3.<br />
WRITE: / &#8216;String 1 and String 3 are identical.&#8217;.<br />
ELSE.<br />
WRITE: / &#8216;String 1 and String 3 are NOT identical.&#8217;.<br />
ENDIF.</p>
<p>运行结果是输出:</p>
<blockquote><p>String 1 and String 2 are identical.</p>
<p>String 1 and String 3 are NOT identical.</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.prglab.com/blog/p/70/feed</wfw:commentRss>
		</item>
		<item>
		<title>简单话内表(internal table)</title>
		<link>http://www.prglab.com/blog/p/69</link>
		<comments>http://www.prglab.com/blog/p/69#comments</comments>
		<pubDate>Thu, 13 Mar 2008 04:44:01 +0000</pubDate>
		<dc:creator>Aqua</dc:creator>
		
		<category><![CDATA[ABAP]]></category>

		<guid isPermaLink="false">http://www.prglab.com/blog/p/69</guid>
		<description><![CDATA[内表是一个运行状态下存在的实例，它在程序开始运行时才生成，在程序结束运行时被销毁。
内表包含两个部分，可有可无的标题行(HeaderLine)，和必需的表身。进出内表的值都必须通过标题行。
程序例子：
* 声明
data: begin of itab occurs 0,
x type c,
y type i,
      end of itab.
* 初始化标题行 headerline
   itab-x = &#8216;d&#8217;.
   itab-y = 34.
  
* 向内表中存入值
appene itab. 
appene itab.
appene itab.
* 读取内表中的值
loop at itab .
write: / itab-x, itab-y.  &#8220;输出列表
endloop.
]]></description>
			<content:encoded><![CDATA[<p><font color="#000000">内表是一个运行状态下存在的实例，它在程序开始运行时才生成，在程序结束运行时被销毁。</font></p>
<p><font color="#000000">内表包含两个部分，可有可无的标题行(HeaderLine)，和必需的表身。</font>进出内表的值都必须通过标题行。</p>
<p><font color="#000000">程序例子：</font></p>
<p><font color="#000000">* 声明</font><br />
<font color="#000000">data: begin of itab occurs 0,</font><br />
<font color="#000000">x type c,</font><br />
<font color="#000000">y type i,</font><br />
<font color="#000000">      end of itab.</font></p>
<p><font color="#000000">* 初始化标题行 headerline</font><br />
<font color="#000000">   itab-x = &#8216;d&#8217;.</font><br />
<font color="#000000">   itab-y = 34.</font><br />
<font color="#000000">  </font><br />
<font color="#000000">* 向内表中存入值</font><br />
<font color="#000000">appene itab. </font><br />
<font color="#000000">appene itab.</font><br />
<font color="#000000">appene itab.</font></p>
<p><font color="#000000">* 读取内表中的值</font><br />
<font color="#000000">loop at itab .</font><br />
<font color="#000000">write: / itab-x, </font><font color="#000000">itab</font><font color="#000000">-y.  &#8220;输出列表</font><br />
<font color="#000000">endloop.</font></p>
]]></content:encoded>
			<wfw:commentRss>http://www.prglab.com/blog/p/69/feed</wfw:commentRss>
		</item>
		<item>
		<title>ABAP内表(internal table)有关的系统变量</title>
		<link>http://www.prglab.com/blog/p/68</link>
		<comments>http://www.prglab.com/blog/p/68#comments</comments>
		<pubDate>Thu, 13 Mar 2008 04:32:34 +0000</pubDate>
		<dc:creator>Aqua</dc:creator>
		
		<category><![CDATA[ABAP]]></category>

		<guid isPermaLink="false">http://www.prglab.com/blog/p/68</guid>
		<description><![CDATA[SY-TABIX &#8211; 内表当前行的索引号。SY-TABIX 的值可以被以下命令修改，但是只适用于索引表(index table)。对于哈希表(Hashed table)，这个系统变量的值为空或0。

APPEND 将 SY-TABIX 的值置为表最后一行的索引号，也就是说它将等于内表的行数。
COLLECT 将 SY-TABIX 的值置为现有或刚刚插入的行的索引号。如果内表为哈希(hashed table)表的话，SY-TABIX 被置为0。
LOOP AT 将 SY-TABIX 的值置为每一次循环开始时的当前行索引号，在整个循环的结束时 SY-TABIX 被恢复为它在进入循环之前的值。对于哈希表(hashed table)，它的值为0。
READ TABLE 将 SY-TABIX 的值置为被读取的行的索引号。如果使用二分查找(binary search)，而没有找到的话，SY-TABIX 将等于所有行数或行数加1。如果是使用顺序查找而没有找到的话，SY-INDEX 没有定义。
SEARCH &#60;itab&#62; FOR 将 SY-TABIX 的值置为找到要查找字符串所在的行的索引号。

SY-TFILL &#8212; 在使用命令 DESCRIBE TABLE、LOOP AT、 和 READ TABLE之后，SY-TFILL 的值为相应内表的行数。
SY-TLENG &#8212; 在使用命令 DESCRIBE TABLE、LOOP AT、和 READ TABLE之后，SY-TLENG 的值为相应内表的行的长度。
SY-TOCCU &#8211; 在使用命令  DESCRIBE TABLE、LOOP AT、和 [...]]]></description>
			<content:encoded><![CDATA[<p><strong>SY-TABIX </strong>&#8211; 内表当前行的索引号。SY-TABIX 的值可以被以下命令修改，但是只适用于索引表(index table)。对于哈希表(Hashed table)，这个系统变量的值为空或0。</p>
<ol>
<li>APPEND 将 SY-TABIX 的值置为表最后一行的索引号，也就是说它将等于内表的行数。</li>
<li>COLLECT 将 SY-TABIX 的值置为现有或刚刚插入的行的索引号。如果内表为哈希(hashed table)表的话，SY-TABIX 被置为0。</li>
<li>LOOP AT 将 SY-TABIX 的值置为每一次循环开始时的当前行索引号，在整个循环的结束时 SY-TABIX 被恢复为它在进入循环之前的值。对于哈希表(hashed table)，它的值为0。</li>
<li>READ TABLE 将 SY-TABIX 的值置为被读取的行的索引号。如果使用二分查找(binary search)，而没有找到的话，SY-TABIX 将等于所有行数或行数加1。如果是使用顺序查找而没有找到的话，SY-INDEX 没有定义。</li>
<li>SEARCH &lt;itab&gt; FOR 将 SY-TABIX 的值置为找到要查找字符串所在的行的索引号。</li>
</ol>
<p><strong>SY-TFILL</strong> &#8212; 在使用命令 DESCRIBE TABLE、LOOP AT、 和 READ TABLE之后，SY-TFILL 的值为相应内表的行数。</p>
<p><strong>SY-TLENG</strong> &#8212; 在使用命令 DESCRIBE TABLE、LOOP AT、和 READ TABLE之后，SY-TLENG 的值为相应内表的行的长度。</p>
<p><strong>SY-TOCCU</strong> &#8211; 在使用命令  DESCRIBE TABLE、LOOP AT、和 READ TABLE之后，SY-TLENG 的值为相应内表所占用的内存。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.prglab.com/blog/p/68/feed</wfw:commentRss>
		</item>
		<item>
		<title>SAP ABAP 性能优化技巧 &#8212;  性能分析的工具</title>
		<link>http://www.prglab.com/blog/p/67</link>
		<comments>http://www.prglab.com/blog/p/67#comments</comments>
		<pubDate>Sun, 09 Mar 2008 04:16:09 +0000</pubDate>
		<dc:creator>Aqua</dc:creator>
		
		<category><![CDATA[ABAP]]></category>

		<guid isPermaLink="false">http://www.prglab.com/blog/p/67</guid>
		<description><![CDATA[以下是SAP提供的各种对ABAP对象进行性能分析的工具：
			
  
 				运行实时分析 transaction SE30

			
 			这个 transaction 可以给出对一个ABAP程序的所有分析，包括数据库和非数据库处理操作。 
			
  
 				SQL 追踪 transaction ST05

			
 				
 				追踪列表有很多行不是关于 SELECT  				语句的，因为任何ABAP程序的执行都会需要很多附加的管理性SQL调用。可以使用过滤器来显示追踪列表的输出来只显示有关的行。  
			
			
 			追踪列表同时包含与一个SELECT语句相关的多个不同 SQL 命令，因为 R/3 数据库接口 &#8212; R/3应用服务器的一个复杂的组成部分 &#8212; 将每一个  			Open SQL 命令映射为一个或一系列的物理数据库调用指令并执行这些指令。这种映射依赖于具体的调用和数据库系统，对R/3的性能是非常重要的。例如在我们的测试程序中，SPFLI表上的	SELECT-ENDSELECT 循环被映射成为一连串Oracle环境下的 PREPARE-OPEN-FETCH 的物理调用。 
			
 				
  追踪列表中的SQL语句的WHERE条件与ABAP语句中的 WHERE 是不同的。因为在 R/3 系统中，客户是一个具有自己的主记录(master records)和自己的一组数据表的独立单元。使用ABAP，每一个 Open SQL 的命令都会自动在相应的客户环境中运行。因此，如果被查找的表有客户(client)字段的话，每一个WHERE语句都会自动添加一个条件包含实际的客户代码。 				
			
要查看一个语句的执行计划（execution plan），只需要将光标放在 PREPARE 语句上，然后选择 [...]]]></description>
			<content:encoded><![CDATA[<p class="MsoNormal"><span lang="EN-US"><font face="Arial"><font size="2">以下是SAP提供的各种对ABAP对象进行性能分析的工具：</font></font></span></p>
<p><font face="Arial">			</font></p>
<ol style="margin-top: 0cm; margin-bottom: 0cm" start="1" type="1">  <font face="Arial"></p>
<li class="MsoNormal"><span lang="EN-US"> 				<font face="Arial" size="2">运行实时分析 transaction SE30</font></span></li>
<p></font></ol>
<p><font face="Arial">			</font></p>
<p class="MsoNormal" style="margin-left: 36pt"><span lang="EN-US"> <font face="Arial">			<font size="2">这个 transaction 可以给出对一个ABAP程序的所有分析，包括数据库和非数据库处理操作。 </font></font></span></p>
<p><font face="Arial">			</font></p>
<ol style="margin-top: 0cm; margin-bottom: 0cm" start="2" type="1">  <font face="Arial"></p>
<li class="MsoNormal"><span lang="EN-US"> 				<font face="Arial" size="2">SQL 追踪 transaction ST05</font></span></li>
<p></font></ol>
<p><font face="Arial">			</font></p>
<blockquote><p> <font face="Arial">				</font></p>
<p class="MsoBodyTextIndent2"><span lang="EN-US"><font face="Arial"><font size="2"> 				追踪列表有很多行不是关于 SELECT  				语句的，因为任何ABAP程序的执行都会需要很多附加的管理性SQL调用。可以使用过滤器来显示追踪列表的输出来只显示有关的行。  </font></font></span></p>
<p><font face="Arial">			</font></p></blockquote>
<p><font face="Arial">			</font></p>
<p class="MsoNormal" style="margin-left: 36pt"><span lang="EN-US"> <font face="Arial">			<font size="2">追踪列表</font></font></span><span lang="EN-US"><font face="Arial"><font size="2">同时</font></font></span><span lang="EN-US"><font face="Arial"><font size="2">包含与一个SELECT语句相关的多个不同 SQL 命令，因为 R/3 数据库接口 &#8212; R/3应用服务器的一个复杂的组成部分 &#8212; 将每一个  			Open SQL 命令映射为一个或一系列的物理数据库调用指令并执行这些指令。这种映射依赖于具体的调用和数据库系统，对R/3的性能是非常重要的。例如在</font></font></span><span lang="EN-US"><font face="Arial"><font size="2">我们的测试程序中，SPFLI表上的</font></font></span><span lang="EN-US"><font face="Arial"><font size="2">	SELECT-ENDSELECT 循环被映射成为一连串Oracle环境下的 PREPARE-OPEN-FETCH 的物理调用。 </font></font></span></p>
<p><font face="Arial">			</font></p>
<blockquote><p> <font face="Arial">				</font></p>
<p class="MsoBodyTextIndent2" style="line-height: 11pt">  <font face="Arial"><span lang="EN-US"></span></font><font face="Arial"><span lang="EN-US"><font size="2">追踪列表中的SQL语句的W</font></span></font><font face="Arial"><span lang="EN-US"><font size="2">HERE条件与ABAP语句中的 WHERE 是不同的。因为在 R/3 系统中，客户是一个</font></span></font><font face="Arial"><span lang="EN-US"><font size="2">具有自己的主记录(master records)和自己的一组数据表的</font></span></font><font face="Arial"><span lang="EN-US"><font size="2">独立单元。使用ABAP，每一个 Open SQL 的命令都会自动在相应的客户环境中运行。因此，如果被查找的表有客户(client)字段的话，每一个WHERE语句都会自动添加一个条件包含</font></span></font><font face="Arial"><span lang="EN-US"><font size="2">实际的客户代码</font></span></font><font face="Arial"><span lang="EN-US"><font size="2">。 				</font></span></font></p>
<p><font face="Arial">			</font></p></blockquote>
<p>要查看一个语句的执行计划（execution plan），只需要将光标放在<font face="Arial"><span lang="EN-US"><font size="2"> PREPARE 语句上，然后选择  			Explain SQL。具体的执行计划的解释取决于使用的数据库。 </font></span></font></p>
<hr /> <center><font size="2"><a href="http://www.prglab.com/blog/p/53">返回文章目录</a></font></center></p>
]]></content:encoded>
			<wfw:commentRss>http://www.prglab.com/blog/p/67/feed</wfw:commentRss>
		</item>
		<item>
		<title>SAP ABAP 性能优化技巧 &#8212; 使用 ABAP “Sort” 取代 “Order By”</title>
		<link>http://www.prglab.com/blog/p/66</link>
		<comments>http://www.prglab.com/blog/p/66#comments</comments>
		<pubDate>Sun, 09 Mar 2008 03:48:42 +0000</pubDate>
		<dc:creator>Aqua</dc:creator>
		
		<category><![CDATA[ABAP]]></category>

		<guid isPermaLink="false">http://www.prglab.com/blog/p/66</guid>
		<description><![CDATA[order by 命令是在数据库服务器上执行的，而 sort 语句是在应用服务器上执行的。因此，与其在select语句中使用order by命令，不如将数据先读取到内表中然后使用sort命令来将结果排序，因为应用服务器上的执行速度要比数据库服务器快。 
 返回文章目录
]]></description>
			<content:encoded><![CDATA[<p><span lang="EN-US"><font face="Arial"><font size="2">order by 命令是在数据库服务器上执行的，而 sort 语句是在应用服务器上执行的。因此，与其在select</font></font></span><span lang="EN-US"><font face="Arial"><font size="2">语句</font></font></span><span lang="EN-US"><font face="Arial"><font size="2">中使用order by</font></font></span><span lang="EN-US"></span><span lang="EN-US"><font face="Arial"><font size="2">命令，不如将数据先读取到内表中然后使用sort命令来将结果排序，因为应用服务器上的执行速度要比数据库服务器快。 </font></font></span><span lang="EN-US"></span></p>
<hr /> <center><font size="2"><a href="http://www.prglab.com/blog/p/53">返回文章目录</a></font></center></p>
]]></content:encoded>
			<wfw:commentRss>http://www.prglab.com/blog/p/66/feed</wfw:commentRss>
		</item>
		<item>
		<title>SAP ABAP 性能优化技巧 &#8212; 正确使用”inner join”</title>
		<link>http://www.prglab.com/blog/p/65</link>
		<comments>http://www.prglab.com/blog/p/65#comments</comments>
		<pubDate>Sun, 09 Mar 2008 03:43:03 +0000</pubDate>
		<dc:creator>Aqua</dc:creator>
		
		<category><![CDATA[ABAP]]></category>

		<guid isPermaLink="false">http://www.prglab.com/blog/p/65</guid>
		<description><![CDATA[当多个  			SAP 表在逻辑上关联的时候，总是建议使用右关联 inner  			join 来从中读取数据。这会降低网络的负载。 
			
以两个表为例：zairln 和 zflight。表 zairln 有字段 airln 存储了航空公司的代码，和字段 lnnam 存储了航空公司的名称。表 zflight 有航空公司代码字段 airln， 以及其他字段存储了航空公司运行的航班的详细信息。
			
既然两个表在逻辑上通过 airln 字段可以关联，建议使用以下 inner join：
			

Select a~airln a~lnnam b~fligh b~cntry into table int_airdet
			
From zairln as a inner join zflight as b on a~airln = b~airln.

			
 这样就可以根据选择条件来限制数据，以上inner join还可以增加 where 条件来进一步限制选择条件。
 返回文章目录
]]></description>
			<content:encoded><![CDATA[<p class="MsoNormal"><span lang="EN-US"><font face="Arial"><font size="2">当多个  			SAP 表在逻辑上关联的时候，总是建议使用右关联 inner  			join 来从中读取数据。这会降低网络的负载。 </font></font></span></p>
<p><font face="Arial">			</font></p>
<p class="MsoNormal"><span lang="EN-US"><font face="Arial"><font size="2">以两个表为例：zairln 和 zflight。表 zairln 有字段 airln 存储了航空公司的代码，和字段 lnnam 存储了航空公司的名称。表 zflight 有航空公司代码字段 airln， 以及其他字段存储了航空公司运行的航班的详细信息。</font></font></span></p>
<p><font face="Arial">			</font></p>
<p class="MsoNormal"><span lang="EN-US"><font face="Arial"><font size="2">既然两个表在逻辑上通过 airln 字段可以关联，建议使用以下 inner join：</font></font></span></p>
<p><font face="Arial">			</font></p>
<blockquote>
<p class="MsoNormal"><font color="#000080"><span lang="EN-US"><font face="Arial"><font size="2">Select a~airln a~lnnam b~fligh b~cntry into table int_airdet</font></font></span></font></p>
<p><font color="#000080" face="Arial">			</font></p>
<p class="MsoNormal"><font color="#000080"><span lang="EN-US"><font face="Arial"><font size="2">From zairln as a inner join zflight as b on a~airln = b~airln.</font></font></span></font></p>
</blockquote>
<p><font color="#000080" face="Arial">			</font></p>
<p class="MsoNormal"><span lang="EN-US"><font face="Arial"><font size="2"> 这样就可以根据选择条件来限制数据，以上inner join还可以增加 where 条件来进一步限制选择条件。</font></font></span></p>
<hr /> <center><font size="2"><a href="http://www.prglab.com/blog/p/53">返回文章目录</a></font></center></p>
]]></content:encoded>
			<wfw:commentRss>http://www.prglab.com/blog/p/65/feed</wfw:commentRss>
		</item>
	</channel>
</rss>
