Powered By Blogger

sexta-feira, 25 de novembro de 2011

PHP - Conversor de DBF para Oracle

 Requisitos:
- SQLLOADER
- SQLPLUS
- Extensão DBASE habilitada no php.ini

 /* Exemplo de utilização da Classe loader */

$loader = new Loader();
//CAMINHO DO DBF
$loader->arquivo_dbf = 'dbf/transcdd.dbf';

//ARQUIVOS GERADOS PELO PROCESSO
$loader->arquivo_ctl = 'tmp/transcdd.ctl';
$loader->arquivo_csv = 'tmp/transcdd.csv';
$loader->arquivo_sql = 'tmp/transcdd.sql';
$loader->arquivo_log = 'tmp/transcdd.log';

//DADOS DE CONEXAO COM O ORACLE
$loader->tabela_oracle = 'transcdd_teste';
$loader->user_db = 'usuario';
$loader->pass_db = 'senha123';
$loader->host_db = '192.168.0.25';
$loader->port_db = '1521';
$loader->service = 'SERVORACLE';


$loader->separador = ';';
$loader->terminador = '||';
$loader->executar();
?>

/* Implementação da Classe loader */


class Loader{
   
    public $arquivo_dbf;
    public $arquivo_csv;
    public $arquivo_sql;
    public $arquivo_log;
    public $tabela_oracle;
   
    public $user_db;
    public $pass_db;
    public $host_db;
    public $port_db;
    public $service;
    public $separador;
    public $terminador;
   
    public function __construct(){
        set_time_limit(0);
    }
   
    public function executar(){
        $this->abrir_dbf();
        $this->obter_campos();
        $this->criar_sql();
        $this->criar_ctl();
        $this->criar_csv();
        $this->criar_tabela();
        $this->popular_tabela();
        $this->fechar_dbf();
    }
   
    public function abrir_dbf() {
        $this->dbf = dbase_open( $this->arquivo_dbf, 0 );
        if( $this->dbf ) {
            return true;
        } else {
            return false;
        }   
    }
   
    public function fechar_dbf() {
        return dbase_close($this->dbf);
    }
   
    //OBTEM INFORMACOES DO DBF
    public function obter_campos() {
        if ($this->dbf) {
            $nf  = dbase_numfields($this->dbf);
            $column_info = dbase_get_header_info($this->dbf);
            $this->campos = array();
            $cont=0;
            for ($e = 0; $e < $nf; $e++) {
                $name         = $column_info[$e]['name'];
                $length     = $column_info[$e]['length'];
                $precision     = $column_info[$e]['precision'];
                switch( $column_info[$e]['type'] ) {
                    case 'date':
                        $this->campos['SQL'][$e]     = "\"$name\" DATE NULL  \r\n";
                        $this->campos['CTL'][$e]     = "$name DATE \"YYYYMMDD\" NULLIF ($name=BLANKS) \r\n";
                        $this->campos['NOME'][$e]     = $column_info[$e]['name'];
                        $this->campos['POS'][$e]     = $cont;
                        $cont++;
                        break;
                    case 'character':
                        $this->campos['SQL'][$e]     = "\"$name\" VARCHAR2($length BYTE) \r\n";
                        $this->campos['CTL'][$e]     = "$name \r\n";
                        $this->campos['NOME'][$e]     = $column_info[$e]['name'];
                        $this->campos['POS'][$e]     = $cont;
                        $cont++;
                        break;
                    case 'boolean':
                        $this->campos['SQL'][$e]     = "\"$name\" CHAR(1 BYTE) \r\n";
                        $this->campos['CTL'][$e]     = "$name \r\n";
                        $this->campos['NOME'][$e]     = $column_info[$e]['name'];
                        $this->campos['POS'][$e]     = $cont;
                        $cont++;
                        break;
                    case 'memo':
                        break;
                    case 'number':
                        $this->campos['SQL'][$e]     = "\"$name\" NUMBER($length,$precision) \r\n";
                        $this->campos['CTL'][$e]     = $name . ( ($precision) ? "\"REPLACE(:$name, '.', ',')\" \r\n" :  " \r\n"   );
                        $this->campos['NOME'][$e]     = $column_info[$e]['name'];
                        $this->campos['POS'][$e]     = $cont;
                        $cont++;
                        break;
                    default:
                        $this->campos['SQL'][$e]     = "\"$name\" \r\n";
                        $this->campos['CTL'][$e]     = "$name \r\n";
                        $this->campos['NOME'][$e]     = $column_info[$e]['name'];
                        $this->campos['POS'][$e]     = $cont;
                        $cont++;
                        break;
                }
            }
        }
    }
   
    //CRIA O CTL DA TABELA
    public function criar_ctl() {
          $campos = implode( ',', $this->campos['CTL'] );
        $fp = fopen( $this->arquivo_ctl, 'w+' );
          fwrite( $fp, "LOAD DATA \r\n" );
          fwrite( $fp, "INFILE '$this->arquivo_csv' \r\n" );
          fwrite( $fp, "INTO TABLE {$this->tabela_oracle} \r\n" );
          fwrite( $fp, "FIELDS TERMINATED BY \"$this->separador\" OPTIONALLY ENCLOSED BY '$this->terminador' \r\n" );
          fwrite( $fp, "TRAILING NULLCOLS \r\n" );
          fwrite( $fp, "(       \r\n" );
          fwrite( $fp, $campos );
          fwrite( $fp, ")       \r\n" );
          fclose( $fp );
    }
   
    //CRIA O CSV DA TABELA
    public function criar_csv() {
        $fp = fopen( $this->arquivo_csv, 'w+' );
        $record_numbers = dbase_numrecords($this->dbf);
        for ($i = 1; $i <= $record_numbers; $i++) {
            $campos = array();
            $rec = dbase_get_record($this->dbf, $i);
            foreach ( $this->campos['POS'] as $e ) {
                $campos[] = $this->terminador.$rec[$e].$this->terminador;
            }
              $campos = implode( "$this->separador", $campos );
              fwrite( $fp, $campos."\r\n" );
        }
        fclose( $fp );
    }
   
    //CRIA O DDL DA TABELA
    public function criar_sql(){
          $campos = implode( ',', $this->campos['SQL'] );
        $fo = fopen( $this->arquivo_sql, 'w+' );
          fwrite( $fo, "DROP TABLE {$this->tabela_oracle}; \r\n" );
          fwrite( $fo, "CREATE TABLE {$this->tabela_oracle} ( \r\n " . $campos ."); \r\n" );
          fwrite( $fo, "EXIT; \r\n" );
          fclose( $fo );
    }

    //EXECUTA A DDL DA TABELA
    public function criar_tabela(){
        $comando = "sqlplus -S $this->user_db/$this->pass_db@$this->host_db:$this->port_db/$this->service @{$this->arquivo_sql}";
        exec( $comando );   
    }
   
    //EXECUTA A CARGA DE DADOS
    public function popular_tabela(){
        $comando = "sqlldr $this->user_db/$this->pass_db@$this->host_db:$this->port_db/$this->service control=$this->arquivo_ctl log=$this->arquivo_log";
        exec( $comando );   
    }
   
}
?>

quinta-feira, 17 de março de 2011

Exemplo de Trigger no Oracle

CREATE OR REPLACE
TRIGGER FDV_DETALHE_LIBERACAO
AFTER INSERT OR DELETE OR UPDATE ON RH_SALARIO
FOR EACH ROW
BEGIN
    IF UPDATING THEN
              INSERT INTO RH_AUDITORIA_SALARIO ( CPF, MOTIVO, DATA_ALTERACAO, USUARIO, VALOR_SALARIO ) VALUES ( :OLD.CPF, :OLD.MOTIVO, :OLD.DATA_ALTERACAO, :OLD.USUARIO, :OLD.VALOR_SALARIO );
    ELSIF DELETING THEN
        INSERT INTO RH_AUDITORIA_SALARIO ( CPF, MOTIVO, DATA_ALTERACAO, USUARIO, VALOR_SALARIO ) VALUES ( :OLD.CPF, :OLD.MOTIVO, :OLD.DATA_ALTERACAO, :OLD.USUARIO, :OLD.VALOR_SALARIO );
    ELSIF INSERTING THEN
        INSERT INTO RH_AUDITORIA_SALARIO ( CPF, MOTIVO, DATA_ALTERACAO, USUARIO, VALOR_SALARIO ) VALUES (:NEW.CPF, :NEW.MOTIVO, :NEW.DATA_ALTERACAO, :NEW.USUARIO, :NEW.VALOR_SALARIO );
    END IF;
END;

terça-feira, 27 de julho de 2010

Utilizando ADODB do PHP para inserir registros em campos do tipo CLOB no Oracle

Quando precisamos registrar em uma tabela do Oracle um campo que possua mais de 4000 caractéres, temos como opção o tipo CLOB, que é um dos "equivalentes" ao tipo TEXT do MySQL por exemplo. A única coisa que deve ser observada para utilizar esse tipo de formato de dado, é que o procedimento de inserir o registro na tabela é feito em duas etapas, sendo que na primeira etapa é realizado o insert com um valor nulo para o campo CLOB, e na segunda etapa é realizado o update do mesmo registro que acabou de ser inserido, só que desta vez deve ser passado o valor do campo CLOB.

Abaixo segue um exemplo utilizando os métodos Execute e UpdateClob da classe AdoDB para PHP.

1) DDL de criação da tabela que contém um campo CLOB:

CREATE TABLE XML_SERASA
(
"CNPJ" VARCHAR2(30 BYTE),
"DATA_SERASA" NUMBER(8,0),
"XML" CLOB
) ;

2) Código que implementa a inserção de um registro na tabela XML_SERASA.

$this->db->StartTrans();
$this->db->Execute("insert into XML_SERASA ( CNPJ, DATA_SERASA, XML ) values ( '$requisitado', '$data_cons', null)");
$sucesso = $this->db->UpdateClob('XML_SERASA', 'XML', $xml, "CNPJ = '$requisitado' AND DATA_SERASA = '$data_cons'");
$this->db->CompleteTrans();

quinta-feira, 1 de julho de 2010

Configurar o PHP para acessar o Oracle em servidor remoto

Habilitar o PHP para acessar o banco de dados Oracle em um servidor remoto não é algo complicado, porém não é tão simples como habilitar outras extensões como por exemplo mysql e postgresql. Isso porque além de editar o arquivo php.ini para ficar com a extensão oci8 (extensão que permite acesso ao Oracle), é necessário instalar um software client da Oracle, o chamado Oracle Instant Client. Outro detalhe é que para a versão 11g do Oracle, é recomendado habilitar a extensão oci8_11g ao invés da oci8.

No site da Oracle é possível garimpar algumas informações técnicas sobre o assunto.

Leitura recomendada:
http://wiki.oracle.com/page/PHP+Oracle+FAQ
http://www.oracle.com/technetwork/articles/technote-php-instant-084410.html
http://www.oracle.com/technology/pub/notes/technote_php_instant.html

segunda-feira, 3 de maio de 2010

Zend Debugger com Zend Optimizer no XAMPP

Depois de baixar o Zend Debugger, as instruções padrões do LEIAME não funcionarão - o PHP se recusa a carregar o Zend Debugger antes do Zend Optimizer.

Você precisa configurar o Zend Debugger usando o mesmo Zend Extension Manager, que o Zend Optimizer usa para se carregar.

Coloque o conteudo do ZendDebugger-5.2.x-cygwin_nt-i386.zip na pasta C:\xampp\php\zendOptimizer\lib.



então renomeie a pasta "ZendDebugger-5.2.x-cygwin_nt-i386? para "Debugger",



A seguir renomeie as pastas para 4_3_x_comp, 5_2_x_comp, etc. para php-4.3.x, php-5.2.x etc. ( procure no diretório ..\Optimizer para referência ). Cada dir …\lib\Debugger\php-X.X.x contêm ZendDebugger.dll.



A seguir edite a seção [Zend] em C:\xampp\php\php.ini (ou C:\xampp\apache\bin\php.ini – verifique seu phpinfo() para ver qual seu PHP está usando).




A opção crítica é "zend_extension_manager.debug_server_ts", que aponta para o diretório contendo os diretórios dll php-X.X.x debugger. Após a edição, o conteúdo da secão Zend no php.ini ficará como a seguir:


[Zend]
zend_extension_ts = "C:\xampp\php\zendOptimizer\lib\ZendExtensionManager.dll"
zend_extension_manager.verbose=On
zend_extension_manager.optimizer_ts = "C:\xampp\php\zendOptimizer\lib\Optimizer"
zend_optimizer.enable_loader = 0
zend_optimizer.optimization_level=15
;zend_optimizer.license_path =
zend_extension_manager.debug_server_ts = "C:\xampp\php\zendOptimizer\lib\Debugger"
zend_debugger.expose_remotely=allowed_hosts
zend_debugger.allow_hosts=127.0.0.1/24,192.168.0.0/16
zend_debugger.allow_tunnel=127.0.0.1/32

Em seguida reinicie o Apache, abra http://localhost/xampp/phpinfo.php e veja se o Zend Debugger está habilitado.

Veja na figura a seguir o processo de Debug no Zend Studio 5.1.



Boa sorte.

fonte original: http://tomasz.sterna.tv/2009/03/zend-debugger-with-zend-optimizer-on-xampp/

Tradução, Adaptação e Imagens por Genivan S. Souza

quarta-feira, 28 de abril de 2010

Problema quando o localhost do Windows XP não responde no ip 127.0.0.1

Para que o Windows XP entenda que o ip 127.0.0.1 responde pelo localhost, é necessário que o arquivo C:\WINDOWS\system32\drivers\etc\hosts tenha este formato:

# Copyright (c) 1993-1999 Microsoft Corp.
#
# Este é um arquivo HOSTS de exemplo usado pelo Microsoft TCP/IP para Windows.
#
# Este arquivo contém os mapeamentos de endereços IP para nomes de host. Cada
# entrada deve ser mantida em uma linha individual. O endereço IP deve
# ser colocado na primeira coluna, seguido do nome de host correspondente.
# O endereço IP e o nome do host devem ser separados por pelo menos um
# espaço.
#
# Adicionalmente, comentários (como estes) podem ser inseridos em linhas
# individuais ou após o nome de computador indicado por um símbolo '#'.
#
# Por exemplo:
#
# 102.54.94.97 rino.acme.com # servidor de origem
# 38.25.63.10 x.acme.com # host cliente x

127.0.0.1 localhost

domingo, 18 de abril de 2010

Script para fazer redução de espaço dos arquivos de dados e de log no SQL Server

/* o limite de redução é o da ocupação física dos arquivos */


DECLARE @bancodedados varchar(50)
DECLARE @arquivodata varchar(50)
DECLARE @arquivolog varchar(50)
DECLARE @tamanhoarquivolog int
DECLARE @tamanhoarquivodata int


SET @bancodedados = 'TreinaUniversus' -- entre com o nome da base de dados
SET @arquivodata = 'Universus_Data' -- entre com o nome LÓGICO do arquivo de dados
SET @arquivolog = 'Universus_Log' -- entre com o nome LÓGICO do arquivo de LOG
SET @tamanhoarquivodata = '1000' -- em MB
SET @tamanhoarquivolog = '1000' -- em MB


Use @bancodedados
dbcc shrinkfile(@arquivodata, @tamanhoarquivodata)
go


Use @bancodedados
go
dbcc shrinkfile(@arquivolog, @tamanhoarquivolog)
go

Modelo de função definida pelo usuário para fazer auditoria em operações de DML no SQL Server

CREATE FUNCTION dbo.GET_AUDIT_TRIGGER_NAME(@TABLENAME VARCHAR(255), @ACTION VARCHAR(6))

RETURNS VARCHAR(30)

AS

BEGIN

DECLARE @PREFIX VARCHAR(4)

IF UPPER(@ACTION) = 'INSERT'

SET @PREFIX = 'TIA_'

ELSE IF UPPER(@ACTION) = 'UPDATE'

SET @PREFIX = 'TUA_'

ELSE IF UPPER(@ACTION) = 'DELETE'

SET @PREFIX = 'TDA_'

RETURN @PREFIX + @TABLENAME

END

Script do MySql para importação de arquivo CSV

LOAD DATA LOCAL INFILE '/tmp/phphTbThl'
REPLACE
INTO TABLE `ped_geral`
FIELDS TERMINATED BY ';'
LINES TERMINATED BY '\r\n'#

DTS do SQL Server 2000 foi substituido pelo SSIS

No SQL Server 2005 o DTS do SQL Server 2000 foi substituido pelo SSIS (SQL Server Integration Services), um livro muito bom sobre o assunto é:
Microsoft SQL Server 2005 Integration Services: Step by Step
Paul Turley;
Hitachi Consulting

Script para reindexar tabelas em um banco SQL Server

DECLARE @NomeTabela varchar(50)

DECLARE CURSOR_TABLES CURSOR
FOR SELECT Table_Name FROM INFORMATION_SCHEMA.TABLES WHERE INFORMATION_SCHEMA.TABLES.TABLE_TYPE = 'BASE TABLE'

OPEN CURSOR_TABLES

FETCH NEXT FROM CURSOR_TABLES INTO @NomeTabela

WHILE @@FETCH_STATUS = 0
BEGIN
PRINT @NomeTabela
DBCC DBREINDEX(@NomeTabela)

FETCH NEXT FROM CURSOR_TABLES INTO @NomeTabela
END
CLOSE CURSOR_TABLES
DEALLOCATE CURSOR_TABLES

Trocar a porta padrão do Mysql durante a instalação do Xampp no Windows

Para trocar a porta padrão do mysql durante a instalação do Xampp, simplesmente é necessário editar o arquivo my.cnf, alterando a porta 3306 para uma outra qualquer que se pretenda utilizar.
Os únicos detalhes que devem ser observados, é que a edição do arquivo my.cnf deve ser feita antes de instalar e iniciar o serviço mysql, além disso, é recomendado trocar o nome do serviço mysql que por padrão assume o nome de mysql.

quarta-feira, 17 de fevereiro de 2010

Warning: fsockopen(): php_network_getaddresses: getaddrinfo failed:

Num sistema web/Desktop em php, a mensagem de Warning: fsockopen(): php_network_getaddresses: getaddrinfo failed: pode ser causada por configuração incorreta do DNS.

Obs.: o fsockopen usa o DNS para fazer a conexão com o host, já um browser pode estar usando o Proxy.

quinta-feira, 11 de fevereiro de 2010

UNIX TIME NO ORACLE (TIMESTAMP)

Função para retornar o timestamp(UNIX TIME em segundos) no formato DD/MM/YYYY HH24:MI:SS

Exemplo de utilização da função:

select fc_timestamp_to_date( pedidos.timestamp ), pedidos.codigo from pedidos order by pedidos.codigo desc


DDL da função:



terça-feira, 9 de fevereiro de 2010

Relacionamento Ternário

Num relacionamento ternário, as 3 entidades estão associadas simultaneamente, sendo que a cardinalidade, neste caso, refere-se à quantidade de ocorrências de uma entidade em relação ao par das outras entidades.


Fonte: http://www.estv.ipv.pt/paginaspessoais/ajas/AS/Apontamentos%20Te%C3%B3ricos/as_2_2.pdf

quarta-feira, 27 de janeiro de 2010

Como fazer apresentações no estilo Steve Jobs



Três atos:
Ato 1 - Crie uma história
Ato 2 - Entregue uma experiência
Ato 3 - Refine e ensaie

“Ato I”
1 - Encontre algo que você ama

Para convencer o público de algo, é preciso convencer a si mesmo. O tom “messiânico” de Jobs só não soa ridículo, porque ele realmente acredita no que diz. Para justificar o trecho, Carmine Gallo usa a seguinte frase de Jobs: “Você deve encontrar o que você ama. O que realmente importa é ir para a cama de noite dizendo 'Fiz alguma coisa maravilhosa"

2 – Planeje
Antes de abrir o PowerPoint pegue um papel e rabisque suas idéias. Planeje como será a apresentação. Os especialistas recomendam que você divida seu tempo privilegiando as ideias: coletando dados, organizando eles e rabiscando uma história.

3 – Crie sempre um vilão
Todas as apresentações de Jobs são baseadas no modelo de herói contra vilão, em que o produto da Apple é a solução para uma situação antagônica ou um concorrente. Em 1984, por exemplo, o papel coube a IBM.

“Ato II”
1 – “Simplicidade é o máximo da sofisticação”

A frase acima, também de Steve Jobs, resume esse passo que indica: jamais use bullets, quando puder imagens ao invés de texto e cada slide deve ter, no máximo, 40 caracteres.

2 – Não use jargão
Jobs pouco fala de gigabytes. Ele prefere dizer que “no iPod cabem mil músicas”. Faça o mesmo, simplificando os termos técnicos sem usar definições abstratas.

“Ato III”
1 - Presença de Palco

Olho nos olhos da platéia, tenha uma postura aberta e com autoridade e saiba se expressar usando as mãos. Como fazer tudo isso? Use o próximo passo como mantra.

2 – Treine
Um repórter da revista BussinessWeek que acompanhou Steve Jobs escreveu que ele “treina sua naturalidade por muitas horas, por muitos dias”. Os treinos do CEO se intensificam nas 48 horas antes do keynote. É quando ele pede feedback da equipe.

3 – Se divirta
Durante um problema na MacWorld de 2007, Jobs aproveitou para contar uma piada sobre os velhos tempos da Apple. Assim, minimizou a falha na apresentação e mostrou confiança. A lição é que é importante entreter o público sempre.

Publicação original:http://info.abril.com.br/dicas/como-se-faz/dicas/como-fazer-apresentacoes-no-estilo-steve-jobs.shtml




quarta-feira, 18 de novembro de 2009

Download de Arquivo Texto em PHP

$arquivo = $caminho_completo_do_arquivo . 'nome_arquivo.txt';
@header("Pragma: public");
@header("Expires: 1");
@header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
@header("Cache-Control: private",false);
@header("Content-Type: text/plain");
@header("Content-Disposition: attachment; filename=\"nome_arquivo.txt\";");
@header("Content-Transfer-Encoding: binary");
@header("Content-Length: " . (int)filesize($arquivo) + 1 );
readfile( $arquivo );

quinta-feira, 1 de outubro de 2009

Popup de alerta de msg no Pidgim

para habilitar o Popup de alerta de msg no Pidgim é necessário ir em
Ubuntu > Sistemas > Gerenciador de Pacotes > procurar Pidgim-Guifications - instalar - entrar no Pidgim ir na Aba Plugins e habilitar o Guifications

max_execution_time em streaming de arquivos em php

ini_set( 'max_execution_time', 0 ) não funciona em casos de streaming de arquivos, para contornar esta situação, utilize set_time_limit( 0 ) para deixar ilimitado o tempo de execução do programa PHP.
Em outras palavras, quando é necessário fazer transferências de arquivos, principalmente por upload em ftp, copy_to_stream, file_get_contents e etc, pode exceder o tempo de execução do programa php, e para resolver isso, ao invès de utilizar o
ini_set( 'max_execution_time', 0 ) para deixar o tempo de execução ilimitado, o correto é utilizar o set_time_limit( 0 ).



quinta-feira, 24 de setembro de 2009

Exemplo de Instalação do Tkcvs(Cliente para CVS) no windows

Este é um exemplo de instalação do Tkcvs(Cliente para CVS) no windows incluindo o checkout dos arquivos que estão no repositório

  1. Instalar a Tcl (Tool Command Language) na máquina.
    obs.: baixe o ActiveTcl(arquivo .exe mais recente) e execute
    site de download do activetcl http://www.activestate.com/activetcl/


  2. Baixe o arquivo .zip do Tkcvs e faça a descompactação do mesmo
    site de download do Tkcvs http://www.twobarleycorns.net/tkcvs.html


  3. Execute o arquivo doinstall.tcl
    Após esse passo o tkcvs já deve estar instalado.

    Para testar o tkcvs, baixe(checkout) os arquivos de um repositório.No exemplo abaixo, será utilizado um o Repositório CVS do Projeto DOC-BR conforme as instruções contidas em http://doc.fug.com.br/repositorio-cvs.html. Antes de poressequir, verifique se os arquivos cvs.exe e diff.exe estão no diretório c:\Windows.


  4. Abra o console e digite os comandos
    cd c:\

    cvs -d :pserver:anonymous@cvs.doc-br.berlios.de:/cvsroot/doc-br login

    cvs -d :pserver:anonymous@cvs.doc-br.berlios.de:/cvsroot/doc-br checkout pt_BR.ISO8859-1


  5. Crie a variável de ambiente CVSROOT com o seguinte valor :pserver:anonymous@cvs.doc-br.berlios.de:/cvsroot/doc-br, o caminho para criar a variável de ambiente é clicar com o botão direiro do mouse no ícone Meu Computador >> Propriedades >> Avançado >> Variáveis de Ambiente >> Nova


  6. Reinicie o computador para assegurar que a variável de ambiente foi inicializada.


  7. crie um atalho no Desktop para o arquivo tkcvs.tcl, e de preferência coloque o parâmetro -dir apontando para o diretório pt_BR.ISO8859-1 que foi baixado do repositório.
    Por exemplo: C:\bin\tkcvs.tcl -dir C:\pt_BR.ISO8859-1

A instalação está concluída e com um exemplo de checkout de arquivos.